blob: 21895be2e4f54a34f7676d83c753e1cddb63476a [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;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014320 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014321 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014322
14323 ENTER();
14324
c_manjee1b4ab9a2016-10-26 11:36:55 +053014325 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14326 !pAdapter->dev) {
14327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14328 return 0;
14329 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014330 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014331 if (NULL == pHddCtx) {
14332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014333 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014334 }
14335
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014337 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014338 {
14339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014340 }
14341#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014342 pScanInfo = &pHddCtx->scan_info;
14343
Jeff Johnson295189b2012-06-20 16:38:30 -070014344 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014345 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014346 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014347 __func__, halHandle, pContext, (int) scanId, (int) status);
14348
Kiet Lamac06e2c2013-10-23 16:25:07 +053014349 pScanInfo->mScanPendingCounter = 0;
14350
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014352 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 &pScanInfo->scan_req_completion_event,
14354 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014355 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014356 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014357 hddLog(VOS_TRACE_LEVEL_ERROR,
14358 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014359 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014360 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014361 }
14362
Yue Maef608272013-04-08 23:09:17 -070014363 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014364 {
14365 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014366 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014367 }
14368
14369 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014370 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 {
14372 hddLog(VOS_TRACE_LEVEL_INFO,
14373 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014374 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014375 (int) scanId);
14376 }
14377
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014378#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014379 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014380#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014381 {
14382 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14383 pAdapter);
14384 if (0 > ret)
14385 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014386 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014387
Jeff Johnson295189b2012-06-20 16:38:30 -070014388 /* If any client wait scan result through WEXT
14389 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014390 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014391 {
14392 /* The other scan request waiting for current scan finish
14393 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014394 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014396 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 }
14398 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014399 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 {
14401 struct net_device *dev = pAdapter->dev;
14402 union iwreq_data wrqu;
14403 int we_event;
14404 char *msg;
14405
14406 memset(&wrqu, '\0', sizeof(wrqu));
14407 we_event = SIOCGIWSCAN;
14408 msg = NULL;
14409 wireless_send_event(dev, we_event, &wrqu, msg);
14410 }
14411 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014412 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014413
14414 /* Get the Scan Req */
14415 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014416 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014417
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014418 /* Scan is no longer pending */
14419 pScanInfo->mScanPending = VOS_FALSE;
14420
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014421 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014422 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14424 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014425 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014426#endif
14427
14428 if (pAdapter->dev) {
14429 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14430 pAdapter->dev->name);
14431 }
mukul sharmae7041822015-12-03 15:09:21 +053014432 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014433 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014434 }
14435
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014436 /* last_scan_timestamp is used to decide if new scan
14437 * is needed or not on station interface. If last station
14438 * scan time and new station scan time is less then
14439 * last_scan_timestamp ; driver will return cached scan.
14440 */
14441 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
14442 {
14443 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14444
14445 if ( req->n_channels )
14446 {
14447 for (i = 0; i < req->n_channels ; i++ )
14448 {
14449 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
14450 }
14451 /* store no of channel scanned */
14452 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
14453 }
14454
14455 }
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;
15183
15184 complete(&pScanInfo->scan_req_completion_event);
15185
15186free_mem:
15187 if( scanRequest.SSIDs.SSIDList )
15188 {
15189 vos_mem_free(scanRequest.SSIDs.SSIDList);
15190 }
15191
15192 if( channelList )
15193 vos_mem_free( channelList );
15194
15195 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015196 return status;
15197}
15198
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015199int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15200#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15201 struct net_device *dev,
15202#endif
15203 struct cfg80211_scan_request *request)
15204{
15205 int ret;
15206
15207 vos_ssr_protect(__func__);
15208 ret = __wlan_hdd_cfg80211_scan(wiphy,
15209#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15210 dev,
15211#endif
15212 request);
15213 vos_ssr_unprotect(__func__);
15214
15215 return ret;
15216}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015217
15218void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15219{
15220 v_U8_t iniDot11Mode =
15221 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15222 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15223
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015224 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15225 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015226 switch ( iniDot11Mode )
15227 {
15228 case eHDD_DOT11_MODE_AUTO:
15229 case eHDD_DOT11_MODE_11ac:
15230 case eHDD_DOT11_MODE_11ac_ONLY:
15231#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015232 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15233 sme_IsFeatureSupportedByFW(DOT11AC) )
15234 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15235 else
15236 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015237#else
15238 hddDot11Mode = eHDD_DOT11_MODE_11n;
15239#endif
15240 break;
15241 case eHDD_DOT11_MODE_11n:
15242 case eHDD_DOT11_MODE_11n_ONLY:
15243 hddDot11Mode = eHDD_DOT11_MODE_11n;
15244 break;
15245 default:
15246 hddDot11Mode = iniDot11Mode;
15247 break;
15248 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015249#ifdef WLAN_FEATURE_AP_HT40_24G
15250 if (operationChannel > SIR_11B_CHANNEL_END)
15251#endif
15252 {
15253 /* This call decides required channel bonding mode */
15254 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015255 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015256 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015257 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015258}
15259
Jeff Johnson295189b2012-06-20 16:38:30 -070015260/*
15261 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015262 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015263 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015264int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015265 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15266 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015267{
15268 int status = 0;
15269 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015270 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015271 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 v_U32_t roamId;
15273 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015274 eCsrAuthType RSNAuthType;
15275
15276 ENTER();
15277
15278 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015279 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015280 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015281
15282 status = wlan_hdd_validate_context(pHddCtx);
15283 if (status)
15284 {
Yue Mae36e3552014-03-05 17:06:20 -080015285 return status;
15286 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015287
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15289 {
15290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15291 return -EINVAL;
15292 }
15293
Nitesh Shah9b066282017-06-06 18:05:52 +053015294 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15295
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 pRoamProfile = &pWextState->roamProfile;
15297
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015298 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015299 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015300 hdd_station_ctx_t *pHddStaCtx;
15301 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015302 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015303
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015304 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15305
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015306 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015307 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15308 {
15309 /*QoS not enabled in cfg file*/
15310 pRoamProfile->uapsd_mask = 0;
15311 }
15312 else
15313 {
15314 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015315 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15317 }
15318
15319 pRoamProfile->SSIDs.numOfSSIDs = 1;
15320 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15321 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015322 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015323 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15324 ssid, ssid_len);
15325
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015326 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15327 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15328
Jeff Johnson295189b2012-06-20 16:38:30 -070015329 if (bssid)
15330 {
15331 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015332 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015333 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015334 /* Save BSSID in seperate variable as well, as RoamProfile
15335 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015336 case of join failure we should send valid BSSID to supplicant
15337 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015338 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015340
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015342 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015343 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015344 /* Store bssid_hint to use in the scan filter. */
15345 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15346 WNI_CFG_BSSID_LEN);
15347 /*
15348 * Save BSSID in seperate variable as well, as RoamProfile
15349 * BSSID is getting zeroed out in the association process. And in
15350 * case of join failure we should send valid BSSID to supplicant
15351 */
15352 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15353 WNI_CFG_BSSID_LEN);
15354 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15355 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015356 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015357
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015358
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015359 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15360 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15362 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015363 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015364 /*set gen ie*/
15365 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15366 /*set auth*/
15367 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15368 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015369#ifdef FEATURE_WLAN_WAPI
15370 if (pAdapter->wapi_info.nWapiMode)
15371 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015372 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015373 switch (pAdapter->wapi_info.wapiAuthMode)
15374 {
15375 case WAPI_AUTH_MODE_PSK:
15376 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015377 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015378 pAdapter->wapi_info.wapiAuthMode);
15379 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15380 break;
15381 }
15382 case WAPI_AUTH_MODE_CERT:
15383 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015384 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015385 pAdapter->wapi_info.wapiAuthMode);
15386 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15387 break;
15388 }
15389 } // End of switch
15390 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15391 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15392 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015393 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 pRoamProfile->AuthType.numEntries = 1;
15395 pRoamProfile->EncryptionType.numEntries = 1;
15396 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15397 pRoamProfile->mcEncryptionType.numEntries = 1;
15398 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15399 }
15400 }
15401#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015402#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015403 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015404 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15405 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15406 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015407 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15408 sizeof (tSirGtkOffloadParams));
15409 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015410 }
15411#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015412 pRoamProfile->csrPersona = pAdapter->device_mode;
15413
Jeff Johnson32d95a32012-09-10 13:15:23 -070015414 if( operatingChannel )
15415 {
15416 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15417 pRoamProfile->ChannelInfo.numOfChannels = 1;
15418 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015419 else
15420 {
15421 pRoamProfile->ChannelInfo.ChannelList = NULL;
15422 pRoamProfile->ChannelInfo.numOfChannels = 0;
15423 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015424 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15425 {
15426 hdd_select_cbmode(pAdapter,operatingChannel);
15427 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015428
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015429 /*
15430 * Change conn_state to connecting before sme_RoamConnect(),
15431 * because sme_RoamConnect() has a direct path to call
15432 * hdd_smeRoamCallback(), which will change the conn_state
15433 * If direct path, conn_state will be accordingly changed
15434 * to NotConnected or Associated by either
15435 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15436 * in sme_RoamCallback()
15437 * if sme_RomConnect is to be queued,
15438 * Connecting state will remain until it is completed.
15439 * If connection state is not changed,
15440 * connection state will remain in eConnectionState_NotConnected state.
15441 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15442 * if conn state is eConnectionState_NotConnected.
15443 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15444 * informed of connect result indication which is an issue.
15445 */
15446
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015447 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15448 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015449 {
15450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015451 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015452 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15453 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015454 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015455 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 pAdapter->sessionId, pRoamProfile, &roamId);
15457
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015458 if ((eHAL_STATUS_SUCCESS != status) &&
15459 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15460 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015461
15462 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015463 hddLog(VOS_TRACE_LEVEL_ERROR,
15464 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15465 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015466 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015467 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015468 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015469 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015470
15471 pRoamProfile->ChannelInfo.ChannelList = NULL;
15472 pRoamProfile->ChannelInfo.numOfChannels = 0;
15473
Jeff Johnson295189b2012-06-20 16:38:30 -070015474 }
15475 else
15476 {
15477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15478 return -EINVAL;
15479 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015480 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015481 return status;
15482}
15483
15484/*
15485 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15486 * This function is used to set the authentication type (OPEN/SHARED).
15487 *
15488 */
15489static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15490 enum nl80211_auth_type auth_type)
15491{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015492 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015493 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15494
15495 ENTER();
15496
15497 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015498 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015499 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015500 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015501 hddLog(VOS_TRACE_LEVEL_INFO,
15502 "%s: set authentication type to AUTOSWITCH", __func__);
15503 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15504 break;
15505
15506 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015507#ifdef WLAN_FEATURE_VOWIFI_11R
15508 case NL80211_AUTHTYPE_FT:
15509#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015510 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015511 "%s: set authentication type to OPEN", __func__);
15512 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15513 break;
15514
15515 case NL80211_AUTHTYPE_SHARED_KEY:
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 SHARED", __func__);
15518 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15519 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015520#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015521 case NL80211_AUTHTYPE_NETWORK_EAP:
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 CCKM WPA", __func__);
15524 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15525 break;
15526#endif
15527
15528
15529 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015530 hddLog(VOS_TRACE_LEVEL_ERROR,
15531 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 auth_type);
15533 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15534 return -EINVAL;
15535 }
15536
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015537 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015538 pHddStaCtx->conn_info.authType;
15539 return 0;
15540}
15541
15542/*
15543 * FUNCTION: wlan_hdd_set_akm_suite
15544 * This function is used to set the key mgmt type(PSK/8021x).
15545 *
15546 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015547static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015548 u32 key_mgmt
15549 )
15550{
15551 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15552 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015553 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015554#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015555#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015556#endif
15557#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015558#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015559#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015560 /*set key mgmt type*/
15561 switch(key_mgmt)
15562 {
15563 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015564 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015565#ifdef WLAN_FEATURE_VOWIFI_11R
15566 case WLAN_AKM_SUITE_FT_PSK:
15567#endif
15568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015569 __func__);
15570 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15571 break;
15572
15573 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015574 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015575#ifdef WLAN_FEATURE_VOWIFI_11R
15576 case WLAN_AKM_SUITE_FT_8021X:
15577#endif
15578 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015579 __func__);
15580 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15581 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015582#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015583#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15584#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15585 case WLAN_AKM_SUITE_CCKM:
15586 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15587 __func__);
15588 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15589 break;
15590#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015591#ifndef WLAN_AKM_SUITE_OSEN
15592#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15593 case WLAN_AKM_SUITE_OSEN:
15594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15595 __func__);
15596 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15597 break;
15598#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015599
15600 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015602 __func__, key_mgmt);
15603 return -EINVAL;
15604
15605 }
15606 return 0;
15607}
15608
15609/*
15610 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015611 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015612 * (NONE/WEP40/WEP104/TKIP/CCMP).
15613 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015614static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15615 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015616 bool ucast
15617 )
15618{
15619 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015620 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015621 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15622
15623 ENTER();
15624
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015625 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015626 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015628 __func__, cipher);
15629 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15630 }
15631 else
15632 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015633
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015635 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015636 {
15637 case IW_AUTH_CIPHER_NONE:
15638 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15639 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015640
Jeff Johnson295189b2012-06-20 16:38:30 -070015641 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015642 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015643 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015644
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015646 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015647 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015648
Jeff Johnson295189b2012-06-20 16:38:30 -070015649 case WLAN_CIPHER_SUITE_TKIP:
15650 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15651 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015652
Jeff Johnson295189b2012-06-20 16:38:30 -070015653 case WLAN_CIPHER_SUITE_CCMP:
15654 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15655 break;
15656#ifdef FEATURE_WLAN_WAPI
15657 case WLAN_CIPHER_SUITE_SMS4:
15658 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15659 break;
15660#endif
15661
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015662#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015663 case WLAN_CIPHER_SUITE_KRK:
15664 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15665 break;
15666#endif
15667 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015668 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015669 __func__, cipher);
15670 return -EOPNOTSUPP;
15671 }
15672 }
15673
15674 if (ucast)
15675 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015677 __func__, encryptionType);
15678 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15679 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015680 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 encryptionType;
15682 }
15683 else
15684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015686 __func__, encryptionType);
15687 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15688 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15689 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15690 }
15691
15692 return 0;
15693}
15694
15695
15696/*
15697 * FUNCTION: wlan_hdd_cfg80211_set_ie
15698 * This function is used to parse WPA/RSN IE's.
15699 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015700int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15702 const u8 *ie,
15703#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015704 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015705#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015706 size_t ie_len
15707 )
15708{
15709 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15711 const u8 *genie = ie;
15712#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 v_U16_t remLen = ie_len;
15716#ifdef FEATURE_WLAN_WAPI
15717 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15718 u16 *tmp;
15719 v_U16_t akmsuiteCount;
15720 int *akmlist;
15721#endif
15722 ENTER();
15723
15724 /* clear previous assocAddIE */
15725 pWextState->assocAddIE.length = 0;
15726 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015727 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015728
15729 while (remLen >= 2)
15730 {
15731 v_U16_t eLen = 0;
15732 v_U8_t elementId;
15733 elementId = *genie++;
15734 eLen = *genie++;
15735 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015736
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015737 /* Sanity check on eLen */
15738 if (eLen > remLen) {
15739 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15740 __func__, eLen, elementId);
15741 VOS_ASSERT(0);
15742 return -EINVAL;
15743 }
15744
Arif Hussain6d2a3322013-11-17 19:50:10 -080015745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015746 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015747
15748 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015749 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015750 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015751 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 -070015752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015753 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015754 "%s: Invalid WPA IE", __func__);
15755 return -EINVAL;
15756 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015757 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015758 {
15759 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015760 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015761 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015762
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015763 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015764 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015765 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15766 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015767 VOS_ASSERT(0);
15768 return -ENOMEM;
15769 }
15770 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15771 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15772 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015773
Jeff Johnson295189b2012-06-20 16:38:30 -070015774 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15775 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15776 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15777 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015778 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15779 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015780 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15781 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15782 __func__, eLen);
15783 VOS_ASSERT(0);
15784 return -EINVAL;
15785 }
15786
Jeff Johnson295189b2012-06-20 16:38:30 -070015787 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15788 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15789 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15790 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15791 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15792 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015793 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015794 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015795 {
15796 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015797 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015798 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015799
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015800 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015801 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015802 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15803 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015804 VOS_ASSERT(0);
15805 return -ENOMEM;
15806 }
15807 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15808 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15809 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015810
Jeff Johnson295189b2012-06-20 16:38:30 -070015811 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15812 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15813 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015814#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015815 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15816 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 /*Consider WFD IE, only for P2P Client */
15818 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15819 {
15820 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015821 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015822 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015823
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015824 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015825 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015826 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15827 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015828 VOS_ASSERT(0);
15829 return -ENOMEM;
15830 }
15831 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15832 // WPS IE + P2P IE + WFD IE
15833 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15834 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015835
Jeff Johnson295189b2012-06-20 16:38:30 -070015836 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15837 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15838 }
15839#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015840 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015841 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015842 HS20_OUI_TYPE_SIZE)) )
15843 {
15844 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015845 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015846 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015847
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015848 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015849 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015850 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15851 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015852 VOS_ASSERT(0);
15853 return -ENOMEM;
15854 }
15855 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15856 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015857
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015858 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15859 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15860 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015861 /* Appending OSEN Information Element in Assiciation Request */
15862 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15863 OSEN_OUI_TYPE_SIZE)) )
15864 {
15865 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15866 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15867 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015868
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015869 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015870 {
15871 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15872 "Need bigger buffer space");
15873 VOS_ASSERT(0);
15874 return -ENOMEM;
15875 }
15876 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15877 pWextState->assocAddIE.length += eLen + 2;
15878
15879 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15880 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15881 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15882 }
15883
Abhishek Singh4322e622015-06-10 15:42:54 +053015884 /* Update only for WPA IE */
15885 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15886 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015887
15888 /* populating as ADDIE in beacon frames */
15889 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015890 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015891 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15892 {
15893 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15894 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15895 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15896 {
15897 hddLog(LOGE,
15898 "Coldn't pass "
15899 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15900 }
15901 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15902 else
15903 hddLog(LOGE,
15904 "Could not pass on "
15905 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15906
15907 /* IBSS mode doesn't contain params->proberesp_ies still
15908 beaconIE's need to be populated in probe response frames */
15909 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15910 {
15911 u16 rem_probe_resp_ie_len = eLen + 2;
15912 u8 probe_rsp_ie_len[3] = {0};
15913 u8 counter = 0;
15914
15915 /* Check Probe Resp Length if it is greater then 255 then
15916 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15917 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15918 not able Store More then 255 bytes into One Variable */
15919
15920 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15921 {
15922 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15923 {
15924 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15925 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15926 }
15927 else
15928 {
15929 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15930 rem_probe_resp_ie_len = 0;
15931 }
15932 }
15933
15934 rem_probe_resp_ie_len = 0;
15935
15936 if (probe_rsp_ie_len[0] > 0)
15937 {
15938 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15939 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15940 (tANI_U8*)(genie - 2),
15941 probe_rsp_ie_len[0], NULL,
15942 eANI_BOOLEAN_FALSE)
15943 == eHAL_STATUS_FAILURE)
15944 {
15945 hddLog(LOGE,
15946 "Could not pass"
15947 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15948 }
15949 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15950 }
15951
15952 if (probe_rsp_ie_len[1] > 0)
15953 {
15954 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15955 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15956 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15957 probe_rsp_ie_len[1], NULL,
15958 eANI_BOOLEAN_FALSE)
15959 == eHAL_STATUS_FAILURE)
15960 {
15961 hddLog(LOGE,
15962 "Could not pass"
15963 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15964 }
15965 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15966 }
15967
15968 if (probe_rsp_ie_len[2] > 0)
15969 {
15970 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15971 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15972 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15973 probe_rsp_ie_len[2], NULL,
15974 eANI_BOOLEAN_FALSE)
15975 == eHAL_STATUS_FAILURE)
15976 {
15977 hddLog(LOGE,
15978 "Could not pass"
15979 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15980 }
15981 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15982 }
15983
15984 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15985 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15986 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15987 {
15988 hddLog(LOGE,
15989 "Could not pass"
15990 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15991 }
15992 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015993 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015994 break;
15995 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053015996 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15997 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
15998 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
15999 VOS_ASSERT(0);
16000 return -EINVAL;
16001 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16003 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16004 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16005 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16006 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16007 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016008
Abhishek Singhb16f3562016-01-20 11:08:32 +053016009 /* Appending extended capabilities with Interworking or
16010 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016011 *
16012 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016013 * interworkingService or bsstransition bit is set to 1.
16014 * Driver is only interested in interworkingService and
16015 * bsstransition capability from supplicant.
16016 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016017 * required from supplicat, it needs to be handled while
16018 * sending Assoc Req in LIM.
16019 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016020 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016021 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016022 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016023 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016024 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016025
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016026 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016027 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016028 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16029 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016030 VOS_ASSERT(0);
16031 return -ENOMEM;
16032 }
16033 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16034 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016035
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016036 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16037 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16038 break;
16039 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016040#ifdef FEATURE_WLAN_WAPI
16041 case WLAN_EID_WAPI:
16042 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016043 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016044 pAdapter->wapi_info.nWapiMode);
16045 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016046 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016047 akmsuiteCount = WPA_GET_LE16(tmp);
16048 tmp = tmp + 1;
16049 akmlist = (int *)(tmp);
16050 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16051 {
16052 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16053 }
16054 else
16055 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016056 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016057 VOS_ASSERT(0);
16058 return -EINVAL;
16059 }
16060
16061 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16062 {
16063 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016064 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016065 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016066 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016067 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016068 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
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_CERT;
16072 }
16073 break;
16074#endif
16075 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016076 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016077 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016078 /* when Unknown IE is received we should break and continue
16079 * to the next IE in the buffer instead we were returning
16080 * so changing this to break */
16081 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 }
16083 genie += eLen;
16084 remLen -= eLen;
16085 }
16086 EXIT();
16087 return 0;
16088}
16089
16090/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016091 * FUNCTION: hdd_isWPAIEPresent
16092 * Parse the received IE to find the WPA IE
16093 *
16094 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016095static bool hdd_isWPAIEPresent(
16096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16097 const u8 *ie,
16098#else
16099 u8 *ie,
16100#endif
16101 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016102{
16103 v_U8_t eLen = 0;
16104 v_U16_t remLen = ie_len;
16105 v_U8_t elementId = 0;
16106
16107 while (remLen >= 2)
16108 {
16109 elementId = *ie++;
16110 eLen = *ie++;
16111 remLen -= 2;
16112 if (eLen > remLen)
16113 {
16114 hddLog(VOS_TRACE_LEVEL_ERROR,
16115 "%s: IE length is wrong %d", __func__, eLen);
16116 return FALSE;
16117 }
16118 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16119 {
16120 /* OUI - 0x00 0X50 0XF2
16121 WPA Information Element - 0x01
16122 WPA version - 0x01*/
16123 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16124 return TRUE;
16125 }
16126 ie += eLen;
16127 remLen -= eLen;
16128 }
16129 return FALSE;
16130}
16131
16132/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016133 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016134 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 * parameters during connect operation.
16136 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016137int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016138 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016139 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016140{
16141 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016142 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 ENTER();
16144
16145 /*set wpa version*/
16146 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16147
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016148 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016150 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016151 {
16152 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16153 }
16154 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16155 {
16156 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16157 }
16158 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016159
16160 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016161 pWextState->wpaVersion);
16162
16163 /*set authentication type*/
16164 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16165
16166 if (0 > status)
16167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016168 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016169 "%s: failed to set authentication type ", __func__);
16170 return status;
16171 }
16172
16173 /*set key mgmt type*/
16174 if (req->crypto.n_akm_suites)
16175 {
16176 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16177 if (0 > status)
16178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016180 __func__);
16181 return status;
16182 }
16183 }
16184
16185 /*set pairwise cipher type*/
16186 if (req->crypto.n_ciphers_pairwise)
16187 {
16188 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16189 req->crypto.ciphers_pairwise[0], true);
16190 if (0 > status)
16191 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016192 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 "%s: failed to set unicast cipher type", __func__);
16194 return status;
16195 }
16196 }
16197 else
16198 {
16199 /*Reset previous cipher suite to none*/
16200 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16201 if (0 > status)
16202 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016203 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016204 "%s: failed to set unicast cipher type", __func__);
16205 return status;
16206 }
16207 }
16208
16209 /*set group cipher type*/
16210 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16211 false);
16212
16213 if (0 > status)
16214 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016216 __func__);
16217 return status;
16218 }
16219
Chet Lanctot186b5732013-03-18 10:26:30 -070016220#ifdef WLAN_FEATURE_11W
16221 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16222#endif
16223
Jeff Johnson295189b2012-06-20 16:38:30 -070016224 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16225 if (req->ie_len)
16226 {
16227 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16228 if ( 0 > status)
16229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 __func__);
16232 return status;
16233 }
16234 }
16235
16236 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016237 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016238 {
16239 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16240 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16241 )
16242 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016243 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016244 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016247 __func__);
16248 return -EOPNOTSUPP;
16249 }
16250 else
16251 {
16252 u8 key_len = req->key_len;
16253 u8 key_idx = req->key_idx;
16254
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016255 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016256 && (CSR_MAX_NUM_KEY > key_idx)
16257 )
16258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016259 hddLog(VOS_TRACE_LEVEL_INFO,
16260 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016261 __func__, key_idx, key_len);
16262 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016263 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016264 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016265 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016266 (u8)key_len;
16267 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16268 }
16269 }
16270 }
16271 }
16272
16273 return status;
16274}
16275
16276/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016277 * FUNCTION: wlan_hdd_try_disconnect
16278 * This function is used to disconnect from previous
16279 * connection
16280 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016281int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016282{
16283 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016284 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016285 hdd_station_ctx_t *pHddStaCtx;
16286 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016287 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016288
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016289 ret = wlan_hdd_validate_context(pHddCtx);
16290 if (0 != ret)
16291 {
16292 return ret;
16293 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016294 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16295
16296 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16297
16298 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16299 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016300 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016301 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16302 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016303 /* Indicate disconnect to SME so that in-progress connection or preauth
16304 * can be aborted
16305 */
16306 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16307 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016308 spin_lock_bh(&pAdapter->lock_for_active_session);
16309 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16310 {
16311 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16312 }
16313 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016314 hdd_connSetConnectionState(pHddStaCtx,
16315 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016316 /* Issue disconnect to CSR */
16317 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016318 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016319 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016320 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16321 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16322 hddLog(LOG1,
16323 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16324 } else if ( 0 != status ) {
16325 hddLog(LOGE,
16326 FL("csrRoamDisconnect failure, returned %d"),
16327 (int)status );
16328 result = -EINVAL;
16329 goto disconnected;
16330 }
16331 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016332 &pAdapter->disconnect_comp_var,
16333 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016334 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16335 hddLog(LOGE,
16336 "%s: Failed to disconnect, timed out", __func__);
16337 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016338 }
16339 }
16340 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16341 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016342 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016343 &pAdapter->disconnect_comp_var,
16344 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016345 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016346 {
16347 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016348 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016349 }
16350 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016351disconnected:
16352 hddLog(LOG1,
16353 FL("Set HDD connState to eConnectionState_NotConnected"));
16354 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16355 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016356}
16357
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016358/**
16359 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16360 * @adapter: Pointer to the HDD adapter
16361 * @req: Pointer to the structure cfg_connect_params receieved from user space
16362 *
16363 * This function will start reassociation if bssid hint, channel hint and
16364 * previous bssid parameters are present in the connect request
16365 *
16366 * Return: success if reassociation is happening
16367 * Error code if reassociation is not permitted or not happening
16368 */
16369#ifdef CFG80211_CONNECT_PREV_BSSID
16370static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16371 struct cfg80211_connect_params *req)
16372{
16373 int status = -EPERM;
16374 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16375 hddLog(VOS_TRACE_LEVEL_INFO,
16376 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16377 req->channel_hint->hw_value,
16378 MAC_ADDR_ARRAY(req->bssid_hint));
16379 status = hdd_reassoc(adapter, req->bssid_hint,
16380 req->channel_hint->hw_value,
16381 CONNECT_CMD_USERSPACE);
16382 }
16383 return status;
16384}
16385#else
16386static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16387 struct cfg80211_connect_params *req)
16388{
16389 return -EPERM;
16390}
16391#endif
16392
Abhishek Singhe3beee22017-07-31 15:35:40 +053016393/**
16394 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16395 * connect in HT20 mode
16396 * @hdd_ctx: hdd context
16397 * @adapter: Pointer to the HDD adapter
16398 * @req: Pointer to the structure cfg_connect_params receieved from user space
16399 *
16400 * This function will check if supplicant has indicated to to connect in HT20
16401 * mode. this is currently applicable only for 2.4Ghz mode only.
16402 * if feature is enabled and supplicant indicate HT20 set
16403 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16404 *
16405 * Return: void
16406 */
16407#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16408static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16409 hdd_adapter_t *adapter,
16410 struct cfg80211_connect_params *req)
16411{
16412 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16413 tCsrRoamProfile *roam_profile;
16414
16415 roam_profile = &wext_state->roamProfile;
16416 roam_profile->force_24ghz_in_ht20 = false;
16417 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16418 !(req->ht_capa.cap_info &
16419 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16420 roam_profile->force_24ghz_in_ht20 = true;
16421
16422 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16423 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16424}
16425#else
16426static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16427 hdd_adapter_t *adapter,
16428 struct cfg80211_connect_params *req)
16429{
16430 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16431 tCsrRoamProfile *roam_profile;
16432
16433 roam_profile = &wext_state->roamProfile;
16434 roam_profile->force_24ghz_in_ht20 = false;
16435}
16436#endif
16437
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016438/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016439 * FUNCTION: __wlan_hdd_cfg80211_connect
16440 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016442static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016443 struct net_device *ndev,
16444 struct cfg80211_connect_params *req
16445 )
16446{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016447 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016448 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016449#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16450 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016451 const u8 *bssid_hint = req->bssid_hint;
16452#else
16453 const u8 *bssid_hint = NULL;
16454#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016456 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016457 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016458
16459 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016460
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016461 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16462 TRACE_CODE_HDD_CFG80211_CONNECT,
16463 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016464 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016465 "%s: device_mode = %s (%d)", __func__,
16466 hdd_device_modetoString(pAdapter->device_mode),
16467 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016468
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016469 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016470 if (!pHddCtx)
16471 {
16472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16473 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016474 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016475 }
16476
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016477 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016478 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016479 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016480 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016481 }
16482
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016483 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16484 return -EINVAL;
16485
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016486 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16487 if (0 == status)
16488 return status;
16489
Agarwal Ashish51325b52014-06-16 16:50:49 +053016490
Jeff Johnson295189b2012-06-20 16:38:30 -070016491#ifdef WLAN_BTAMP_FEATURE
16492 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016493 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016495 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016496 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016497 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016498 }
16499#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016500
16501 //If Device Mode is Station Concurrent Sessions Exit BMps
16502 //P2P Mode will be taken care in Open/close adapter
16503 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016504 (vos_concurrent_open_sessions_running())) {
16505 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16506 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016507 }
16508
16509 /*Try disconnecting if already in connected state*/
16510 status = wlan_hdd_try_disconnect(pAdapter);
16511 if ( 0 > status)
16512 {
16513 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16514 " connection"));
16515 return -EALREADY;
16516 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016517 /* Check for max concurrent connections after doing disconnect if any*/
16518 if (vos_max_concurrent_connections_reached()) {
16519 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16520 return -ECONNREFUSED;
16521 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016522
Jeff Johnson295189b2012-06-20 16:38:30 -070016523 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016524 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016525
16526 if ( 0 > status)
16527 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 __func__);
16530 return status;
16531 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016532
16533 if (pHddCtx->spoofMacAddr.isEnabled)
16534 {
16535 hddLog(VOS_TRACE_LEVEL_INFO,
16536 "%s: MAC Spoofing enabled ", __func__);
16537 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16538 * to fill TxBds for probe request during SSID scan which may happen
16539 * as part of connect command
16540 */
16541 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16542 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16543 if (status != VOS_STATUS_SUCCESS)
16544 return -ECONNREFUSED;
16545 }
16546
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016547 if (req->channel)
16548 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016549 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016550 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016551
16552 /* Abort if any scan is going on */
16553 status = wlan_hdd_scan_abort(pAdapter);
16554 if (0 != status)
16555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16556
Abhishek Singhe3beee22017-07-31 15:35:40 +053016557 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16558
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016559 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16560 req->ssid_len, req->bssid,
16561 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016562
Sushant Kaushikd7083982015-03-18 14:33:24 +053016563 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016564 {
16565 //ReEnable BMPS if disabled
16566 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16567 (NULL != pHddCtx))
16568 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016569 if (pHddCtx->hdd_wlan_suspended)
16570 {
16571 hdd_set_pwrparams(pHddCtx);
16572 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 //ReEnable Bmps and Imps back
16574 hdd_enable_bmps_imps(pHddCtx);
16575 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 return status;
16578 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016579 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 EXIT();
16581 return status;
16582}
16583
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016584static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16585 struct net_device *ndev,
16586 struct cfg80211_connect_params *req)
16587{
16588 int ret;
16589 vos_ssr_protect(__func__);
16590 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16591 vos_ssr_unprotect(__func__);
16592
16593 return ret;
16594}
Jeff Johnson295189b2012-06-20 16:38:30 -070016595
16596/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016597 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 * This function is used to issue a disconnect request to SME
16599 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016600static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016601 struct net_device *dev,
16602 u16 reason
16603 )
16604{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016606 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016607 tCsrRoamProfile *pRoamProfile;
16608 hdd_station_ctx_t *pHddStaCtx;
16609 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016610#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016611 tANI_U8 staIdx;
16612#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016613
Jeff Johnson295189b2012-06-20 16:38:30 -070016614 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016615
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016616 if (!pAdapter) {
16617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16618 return -EINVAL;
16619 }
16620
16621 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16622 if (!pHddStaCtx) {
16623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16624 return -EINVAL;
16625 }
16626
16627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16628 status = wlan_hdd_validate_context(pHddCtx);
16629 if (0 != status)
16630 {
16631 return status;
16632 }
16633
16634 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16637 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16638 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16640 __func__, hdd_device_modetoString(pAdapter->device_mode),
16641 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016642
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16644 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016645
Jeff Johnson295189b2012-06-20 16:38:30 -070016646 if (NULL != pRoamProfile)
16647 {
16648 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016649 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16650 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016651 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016652 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016653 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016654 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016655 switch(reason)
16656 {
16657 case WLAN_REASON_MIC_FAILURE:
16658 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16659 break;
16660
16661 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16662 case WLAN_REASON_DISASSOC_AP_BUSY:
16663 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16664 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16665 break;
16666
16667 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16668 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016669 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016670 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16671 break;
16672
Jeff Johnson295189b2012-06-20 16:38:30 -070016673 default:
16674 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16675 break;
16676 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016677 pScanInfo = &pHddCtx->scan_info;
16678 if (pScanInfo->mScanPending)
16679 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016680 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016681 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016682 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016683 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016684 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016685 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016686#ifdef FEATURE_WLAN_TDLS
16687 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016688 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016689 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016690 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16691 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016692 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016693 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016694 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016696 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016697 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016698 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016699 status = sme_DeleteTdlsPeerSta(
16700 WLAN_HDD_GET_HAL_CTX(pAdapter),
16701 pAdapter->sessionId,
16702 mac);
16703 if (status != eHAL_STATUS_SUCCESS) {
16704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16705 return -EPERM;
16706 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016707 }
16708 }
16709#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016710
16711 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16712 reasonCode,
16713 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016714 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16715 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016716 {
16717 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016718 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016719 __func__, (int)status );
16720 return -EINVAL;
16721 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016723 else
16724 {
16725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16726 "called while in %d state", __func__,
16727 pHddStaCtx->conn_info.connState);
16728 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016729 }
16730 else
16731 {
16732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16733 }
16734
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016735 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016736 return status;
16737}
16738
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016739static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16740 struct net_device *dev,
16741 u16 reason
16742 )
16743{
16744 int ret;
16745 vos_ssr_protect(__func__);
16746 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16747 vos_ssr_unprotect(__func__);
16748
16749 return ret;
16750}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016751
Jeff Johnson295189b2012-06-20 16:38:30 -070016752/*
16753 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016754 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016755 * settings in IBSS mode.
16756 */
16757static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016758 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016759 struct cfg80211_ibss_params *params
16760 )
16761{
16762 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016763 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016764 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16765 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016766
Jeff Johnson295189b2012-06-20 16:38:30 -070016767 ENTER();
16768
16769 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016770 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016771
16772 if (params->ie_len && ( NULL != params->ie) )
16773 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016774 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16775 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016776 {
16777 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16778 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16779 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016780 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016781 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016782 tDot11fIEWPA dot11WPAIE;
16783 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016784 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016785
Wilson Yang00256342013-10-10 23:13:38 -070016786 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016787 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16788 params->ie_len, DOT11F_EID_WPA);
16789 if ( NULL != ie )
16790 {
16791 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16792 // Unpack the WPA IE
16793 //Skip past the EID byte and length byte - and four byte WiFi OUI
16794 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16795 &ie[2+4],
16796 ie[1] - 4,
16797 &dot11WPAIE);
16798 /*Extract the multicast cipher, the encType for unicast
16799 cipher for wpa-none is none*/
16800 encryptionType =
16801 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16802 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016803 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016804
Jeff Johnson295189b2012-06-20 16:38:30 -070016805 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16806
16807 if (0 > status)
16808 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016809 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016810 __func__);
16811 return status;
16812 }
16813 }
16814
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016815 pWextState->roamProfile.AuthType.authType[0] =
16816 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016817 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16818
16819 if (params->privacy)
16820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016821 /* Security enabled IBSS, At this time there is no information available
16822 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016823 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016824 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016825 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016826 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016827 *enable privacy bit in beacons */
16828
16829 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16830 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016831 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16832 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16834 pWextState->roamProfile.EncryptionType.numEntries = 1;
16835 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016836 return status;
16837}
16838
16839/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016840 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016841 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016842 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016843static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016844 struct net_device *dev,
16845 struct cfg80211_ibss_params *params
16846 )
16847{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016849 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16850 tCsrRoamProfile *pRoamProfile;
16851 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16853 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016854 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016855
16856 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016857
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016858 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16859 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16860 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016861 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016862 "%s: device_mode = %s (%d)", __func__,
16863 hdd_device_modetoString(pAdapter->device_mode),
16864 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016865
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016866 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016867 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016868 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016869 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016870 }
16871
16872 if (NULL == pWextState)
16873 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016874 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016875 __func__);
16876 return -EIO;
16877 }
16878
Agarwal Ashish51325b52014-06-16 16:50:49 +053016879 if (vos_max_concurrent_connections_reached()) {
16880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16881 return -ECONNREFUSED;
16882 }
16883
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016884 /*Try disconnecting if already in connected state*/
16885 status = wlan_hdd_try_disconnect(pAdapter);
16886 if ( 0 > status)
16887 {
16888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16889 " IBSS connection"));
16890 return -EALREADY;
16891 }
16892
Jeff Johnson295189b2012-06-20 16:38:30 -070016893 pRoamProfile = &pWextState->roamProfile;
16894
16895 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16896 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016897 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016898 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016899 return -EINVAL;
16900 }
16901
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016902 /* BSSID is provided by upper layers hence no need to AUTO generate */
16903 if (NULL != params->bssid) {
16904 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16905 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16906 hddLog (VOS_TRACE_LEVEL_ERROR,
16907 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16908 return -EIO;
16909 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016910 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016911 }
krunal sonie9002db2013-11-25 14:24:17 -080016912 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16913 {
16914 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16915 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16916 {
16917 hddLog (VOS_TRACE_LEVEL_ERROR,
16918 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16919 return -EIO;
16920 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016921
16922 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016923 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016924 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016925 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016926
Jeff Johnson295189b2012-06-20 16:38:30 -070016927 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016928 if (NULL !=
16929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16930 params->chandef.chan)
16931#else
16932 params->channel)
16933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016934 {
16935 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016936 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16937 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16938 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16939 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016940
16941 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016942 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016943 ieee80211_frequency_to_channel(
16944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16945 params->chandef.chan->center_freq);
16946#else
16947 params->channel->center_freq);
16948#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016949
16950 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16951 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016952 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16954 __func__);
16955 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016956 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016957
16958 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016959 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016960 if (channelNum == validChan[indx])
16961 {
16962 break;
16963 }
16964 }
16965 if (indx >= numChans)
16966 {
16967 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016968 __func__, channelNum);
16969 return -EINVAL;
16970 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016971 /* Set the Operational Channel */
16972 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16973 channelNum);
16974 pRoamProfile->ChannelInfo.numOfChannels = 1;
16975 pHddStaCtx->conn_info.operationChannel = channelNum;
16976 pRoamProfile->ChannelInfo.ChannelList =
16977 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016978 }
16979
16980 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016981 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016982 if (status < 0)
16983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016984 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016985 __func__);
16986 return status;
16987 }
16988
16989 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016990 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016991 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016992 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016993
16994 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016997 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016998 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016999}
17000
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017001static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17002 struct net_device *dev,
17003 struct cfg80211_ibss_params *params
17004 )
17005{
17006 int ret = 0;
17007
17008 vos_ssr_protect(__func__);
17009 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17010 vos_ssr_unprotect(__func__);
17011
17012 return ret;
17013}
17014
Jeff Johnson295189b2012-06-20 16:38:30 -070017015/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017016 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017017 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017018 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017019static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017020 struct net_device *dev
17021 )
17022{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017023 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017024 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17025 tCsrRoamProfile *pRoamProfile;
17026 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017027 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017028 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017029#ifdef WLAN_FEATURE_RMC
17030 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17031#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017032
17033 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017034
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017035 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17036 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17037 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017038 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017039 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017040 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017041 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017042 }
17043
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017044 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17045 hdd_device_modetoString(pAdapter->device_mode),
17046 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017047 if (NULL == pWextState)
17048 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017049 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017050 __func__);
17051 return -EIO;
17052 }
17053
17054 pRoamProfile = &pWextState->roamProfile;
17055
17056 /* Issue disconnect only if interface type is set to IBSS */
17057 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017059 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017060 __func__);
17061 return -EINVAL;
17062 }
17063
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017064#ifdef WLAN_FEATURE_RMC
17065 /* Clearing add IE of beacon */
17066 if (ccmCfgSetStr(pHddCtx->hHal,
17067 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17068 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17069 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17070 {
17071 hddLog (VOS_TRACE_LEVEL_ERROR,
17072 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17073 return -EINVAL;
17074 }
17075 if (ccmCfgSetInt(pHddCtx->hHal,
17076 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17077 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17078 {
17079 hddLog (VOS_TRACE_LEVEL_ERROR,
17080 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17081 __func__);
17082 return -EINVAL;
17083 }
17084
17085 // Reset WNI_CFG_PROBE_RSP Flags
17086 wlan_hdd_reset_prob_rspies(pAdapter);
17087
17088 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17089 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17090 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17091 {
17092 hddLog (VOS_TRACE_LEVEL_ERROR,
17093 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17094 __func__);
17095 return -EINVAL;
17096 }
17097#endif
17098
Jeff Johnson295189b2012-06-20 16:38:30 -070017099 /* Issue Disconnect request */
17100 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017101 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17102 pAdapter->sessionId,
17103 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17104 if (!HAL_STATUS_SUCCESS(hal_status)) {
17105 hddLog(LOGE,
17106 FL("sme_RoamDisconnect failed hal_status(%d)"),
17107 hal_status);
17108 return -EAGAIN;
17109 }
17110 status = wait_for_completion_timeout(
17111 &pAdapter->disconnect_comp_var,
17112 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17113 if (!status) {
17114 hddLog(LOGE,
17115 FL("wait on disconnect_comp_var failed"));
17116 return -ETIMEDOUT;
17117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017118
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017119 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017120 return 0;
17121}
17122
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017123static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17124 struct net_device *dev
17125 )
17126{
17127 int ret = 0;
17128
17129 vos_ssr_protect(__func__);
17130 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17131 vos_ssr_unprotect(__func__);
17132
17133 return ret;
17134}
17135
Jeff Johnson295189b2012-06-20 16:38:30 -070017136/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017137 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017138 * This function is used to set the phy parameters
17139 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17140 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017141static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017142 u32 changed)
17143{
17144 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17145 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017146 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017147
17148 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017149
17150 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017151 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17152 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017153
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017154 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017155 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017156 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017157 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017158 }
17159
Jeff Johnson295189b2012-06-20 16:38:30 -070017160 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17161 {
17162 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17163 WNI_CFG_RTS_THRESHOLD_STAMAX :
17164 wiphy->rts_threshold;
17165
17166 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017167 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017169 hddLog(VOS_TRACE_LEVEL_ERROR,
17170 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017171 __func__, rts_threshold);
17172 return -EINVAL;
17173 }
17174
17175 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17176 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017177 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017179 hddLog(VOS_TRACE_LEVEL_ERROR,
17180 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017181 __func__, rts_threshold);
17182 return -EIO;
17183 }
17184
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017185 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 rts_threshold);
17187 }
17188
17189 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17190 {
17191 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17192 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17193 wiphy->frag_threshold;
17194
17195 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017196 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017197 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017198 hddLog(VOS_TRACE_LEVEL_ERROR,
17199 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017200 frag_threshold);
17201 return -EINVAL;
17202 }
17203
17204 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17205 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017206 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017208 hddLog(VOS_TRACE_LEVEL_ERROR,
17209 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017210 __func__, frag_threshold);
17211 return -EIO;
17212 }
17213
17214 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17215 frag_threshold);
17216 }
17217
17218 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17219 || (changed & WIPHY_PARAM_RETRY_LONG))
17220 {
17221 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17222 wiphy->retry_short :
17223 wiphy->retry_long;
17224
17225 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17226 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017229 __func__, retry_value);
17230 return -EINVAL;
17231 }
17232
17233 if (changed & WIPHY_PARAM_RETRY_SHORT)
17234 {
17235 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17236 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017237 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017238 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017239 hddLog(VOS_TRACE_LEVEL_ERROR,
17240 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017241 __func__, retry_value);
17242 return -EIO;
17243 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017244 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017245 __func__, retry_value);
17246 }
17247 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17248 {
17249 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17250 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017251 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017252 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017253 hddLog(VOS_TRACE_LEVEL_ERROR,
17254 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017255 __func__, retry_value);
17256 return -EIO;
17257 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017258 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017259 __func__, retry_value);
17260 }
17261 }
17262
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017263 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017264 return 0;
17265}
17266
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017267static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17268 u32 changed)
17269{
17270 int ret;
17271
17272 vos_ssr_protect(__func__);
17273 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17274 vos_ssr_unprotect(__func__);
17275
17276 return ret;
17277}
17278
Jeff Johnson295189b2012-06-20 16:38:30 -070017279/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017280 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017281 * This function is used to set the txpower
17282 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017283static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017284#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17285 struct wireless_dev *wdev,
17286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017287#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017288 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017289#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017290 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017291#endif
17292 int dbm)
17293{
17294 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017295 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017296 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17297 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017298 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017299
17300 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017301
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017302 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17303 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17304 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017305 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017306 if (0 != status)
17307 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017308 return status;
17309 }
17310
17311 hHal = pHddCtx->hHal;
17312
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017313 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17314 dbm, ccmCfgSetCallback,
17315 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017316 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017317 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017318 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17319 return -EIO;
17320 }
17321
17322 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17323 dbm);
17324
17325 switch(type)
17326 {
17327 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17328 /* Fall through */
17329 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17330 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17333 __func__);
17334 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017335 }
17336 break;
17337 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017339 __func__);
17340 return -EOPNOTSUPP;
17341 break;
17342 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17344 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 return -EIO;
17346 }
17347
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017348 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017349 return 0;
17350}
17351
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017352static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17353#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17354 struct wireless_dev *wdev,
17355#endif
17356#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17357 enum tx_power_setting type,
17358#else
17359 enum nl80211_tx_power_setting type,
17360#endif
17361 int dbm)
17362{
17363 int ret;
17364 vos_ssr_protect(__func__);
17365 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17366#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17367 wdev,
17368#endif
17369#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17370 type,
17371#else
17372 type,
17373#endif
17374 dbm);
17375 vos_ssr_unprotect(__func__);
17376
17377 return ret;
17378}
17379
Jeff Johnson295189b2012-06-20 16:38:30 -070017380/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017381 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017382 * This function is used to read the txpower
17383 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017384static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017385#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17386 struct wireless_dev *wdev,
17387#endif
17388 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017389{
17390
17391 hdd_adapter_t *pAdapter;
17392 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017393 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017394
Jeff Johnsone7245742012-09-05 17:12:55 -070017395 ENTER();
17396
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017397 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017398 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017399 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017400 *dbm = 0;
17401 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017402 }
17403
Jeff Johnson295189b2012-06-20 16:38:30 -070017404 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17405 if (NULL == pAdapter)
17406 {
17407 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17408 return -ENOENT;
17409 }
17410
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017411 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17412 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17413 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 wlan_hdd_get_classAstats(pAdapter);
17415 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17416
Jeff Johnsone7245742012-09-05 17:12:55 -070017417 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017418 return 0;
17419}
17420
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017421static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17422#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17423 struct wireless_dev *wdev,
17424#endif
17425 int *dbm)
17426{
17427 int ret;
17428
17429 vos_ssr_protect(__func__);
17430 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17431#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17432 wdev,
17433#endif
17434 dbm);
17435 vos_ssr_unprotect(__func__);
17436
17437 return ret;
17438}
17439
Dustin Brown8c1d4092017-07-28 18:08:01 +053017440/*
17441 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17442 * @stats: summary stats to use as a source
17443 * @info: kernel station_info struct to use as a destination
17444 *
17445 * Return: None
17446 */
17447static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17448 struct station_info *info)
17449{
17450 int i;
17451
17452 info->rx_packets = stats->rx_frm_cnt;
17453 info->tx_packets = 0;
17454 info->tx_retries = 0;
17455 info->tx_failed = 0;
17456
17457 for (i = 0; i < 4; ++i) {
17458 info->tx_packets += stats->tx_frm_cnt[i];
17459 info->tx_retries += stats->multiple_retry_cnt[i];
17460 info->tx_failed += stats->fail_cnt[i];
17461 }
17462
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017463#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17464 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017465 info->filled |= STATION_INFO_TX_PACKETS |
17466 STATION_INFO_TX_RETRIES |
17467 STATION_INFO_TX_FAILED |
17468 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017469#else
17470 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17471 BIT(NL80211_STA_INFO_TX_RETRIES) |
17472 BIT(NL80211_STA_INFO_TX_FAILED) |
17473 BIT(NL80211_STA_INFO_RX_PACKETS);
17474#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017475}
17476
17477/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017478 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17479 * @adapter: sap adapter pointer
17480 * @staid: station id of the client
17481 * @rssi: rssi value to fill
17482 *
17483 * Return: None
17484 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017485void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017486wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17487{
17488 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17489
17490 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17491}
17492
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017493#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17494 !defined(WITH_BACKPORTS)
17495static inline void wlan_hdd_fill_station_info_signal(struct station_info
17496 *sinfo)
17497{
17498 sinfo->filled |= STATION_INFO_SIGNAL;
17499}
17500#else
17501static inline void wlan_hdd_fill_station_info_signal(struct station_info
17502 *sinfo)
17503{
17504 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17505}
17506#endif
17507
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017508/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017509 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17510 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017511 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017512 * @info: kernel station_info struct to populate
17513 *
17514 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17515 * support "station dump" and "station get" for SAP vdevs, even though they
17516 * aren't technically stations.
17517 *
17518 * Return: errno
17519 */
17520static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017521wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17523 const u8* mac,
17524#else
17525 u8* mac,
17526#endif
17527 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017528{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017529 v_MACADDR_t *peerMacAddr;
17530 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017531 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017532 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017533
17534 status = wlan_hdd_get_station_stats(adapter);
17535 if (!VOS_IS_STATUS_SUCCESS(status)) {
17536 hddLog(VOS_TRACE_LEVEL_ERROR,
17537 "Failed to get SAP stats; status:%d", status);
17538 return 0;
17539 }
17540
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017541 peerMacAddr = (v_MACADDR_t *)mac;
17542 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17543 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17544 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17545
17546 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17547 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017548 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017549 }
17550
Dustin Brown8c1d4092017-07-28 18:08:01 +053017551 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17552
17553 return 0;
17554}
17555
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017556static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17558 const u8* mac,
17559#else
17560 u8* mac,
17561#endif
17562 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017563{
17564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17565 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17566 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017567 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017568
17569 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17570 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017571
17572 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17573 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17574 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17575 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17576 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17577 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17578 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017579 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017580 tANI_U16 myRate;
17581 tANI_U16 currentRate = 0;
17582 tANI_U8 maxSpeedMCS = 0;
17583 tANI_U8 maxMCSIdx = 0;
17584 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017585 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017586 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017587 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017588
Leo Chang6f8870f2013-03-26 18:11:36 -070017589#ifdef WLAN_FEATURE_11AC
17590 tANI_U32 vht_mcs_map;
17591 eDataRate11ACMaxMcs vhtMaxMcs;
17592#endif /* WLAN_FEATURE_11AC */
17593
Jeff Johnsone7245742012-09-05 17:12:55 -070017594 ENTER();
17595
Dustin Brown8c1d4092017-07-28 18:08:01 +053017596 status = wlan_hdd_validate_context(pHddCtx);
17597 if (0 != status)
17598 {
17599 return status;
17600 }
17601
17602 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017603 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017604
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17606 (0 == ssidlen))
17607 {
17608 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17609 " Invalid ssidlen, %d", __func__, ssidlen);
17610 /*To keep GUI happy*/
17611 return 0;
17612 }
17613
Mukul Sharma811205f2014-07-09 21:07:30 +053017614 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17615 {
17616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17617 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017618 /* return a cached value */
17619 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017620 return 0;
17621 }
17622
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017623 wlan_hdd_get_station_stats(pAdapter);
17624 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017625
Kiet Lam3b17fc82013-09-27 05:24:08 +053017626 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017627 wlan_hdd_get_snr(pAdapter, &snr);
17628 pHddStaCtx->conn_info.signal = sinfo->signal;
17629 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017630 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017631
c_hpothu09f19542014-05-30 21:53:31 +053017632 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017633 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17634 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017635 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017636 {
17637 rate_flags = pAdapter->maxRateFlags;
17638 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017639
Jeff Johnson295189b2012-06-20 16:38:30 -070017640 //convert to the UI units of 100kbps
17641 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17642
17643#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017644 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 -070017645 sinfo->signal,
17646 pCfg->reportMaxLinkSpeed,
17647 myRate,
17648 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017649 (int) pCfg->linkSpeedRssiMid,
17650 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017651 (int) rate_flags,
17652 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017653#endif //LINKSPEED_DEBUG_ENABLED
17654
17655 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17656 {
17657 // we do not want to necessarily report the current speed
17658 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17659 {
17660 // report the max possible speed
17661 rssidx = 0;
17662 }
17663 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17664 {
17665 // report the max possible speed with RSSI scaling
17666 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17667 {
17668 // report the max possible speed
17669 rssidx = 0;
17670 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017671 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017672 {
17673 // report middle speed
17674 rssidx = 1;
17675 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017676 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17677 {
17678 // report middle speed
17679 rssidx = 2;
17680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017681 else
17682 {
17683 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017684 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017685 }
17686 }
17687 else
17688 {
17689 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17690 hddLog(VOS_TRACE_LEVEL_ERROR,
17691 "%s: Invalid value for reportMaxLinkSpeed: %u",
17692 __func__, pCfg->reportMaxLinkSpeed);
17693 rssidx = 0;
17694 }
17695
17696 maxRate = 0;
17697
17698 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017699 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17700 OperationalRates, &ORLeng))
17701 {
17702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17703 /*To keep GUI happy*/
17704 return 0;
17705 }
17706
Jeff Johnson295189b2012-06-20 16:38:30 -070017707 for (i = 0; i < ORLeng; i++)
17708 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017709 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017710 {
17711 /* Validate Rate Set */
17712 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17713 {
17714 currentRate = supported_data_rate[j].supported_rate[rssidx];
17715 break;
17716 }
17717 }
17718 /* Update MAX rate */
17719 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17720 }
17721
17722 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017723 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17724 ExtendedRates, &ERLeng))
17725 {
17726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17727 /*To keep GUI happy*/
17728 return 0;
17729 }
17730
Jeff Johnson295189b2012-06-20 16:38:30 -070017731 for (i = 0; i < ERLeng; i++)
17732 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017733 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017734 {
17735 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17736 {
17737 currentRate = supported_data_rate[j].supported_rate[rssidx];
17738 break;
17739 }
17740 }
17741 /* Update MAX rate */
17742 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17743 }
c_hpothu79aab322014-07-14 21:11:01 +053017744
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017745 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017746 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017747 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017748 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017749 {
c_hpothu79aab322014-07-14 21:11:01 +053017750 if (rate_flags & eHAL_TX_RATE_VHT80)
17751 mode = 2;
17752 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17753 mode = 1;
17754 else
17755 mode = 0;
17756
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017757 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17758 MCSRates, &MCSLeng))
17759 {
17760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17761 /*To keep GUI happy*/
17762 return 0;
17763 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017764 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017765#ifdef WLAN_FEATURE_11AC
17766 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017767 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017768 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017769 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017770 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017771 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017772 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017773 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017774 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017775 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017776 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017777 maxMCSIdx = 7;
17778 }
17779 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17780 {
17781 maxMCSIdx = 8;
17782 }
17783 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17784 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017785 //VHT20 is supporting 0~8
17786 if (rate_flags & eHAL_TX_RATE_VHT20)
17787 maxMCSIdx = 8;
17788 else
17789 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017790 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017791
c_hpothu79aab322014-07-14 21:11:01 +053017792 if (0 != rssidx)/*check for scaled */
17793 {
17794 //get middle rate MCS index if rssi=1/2
17795 for (i=0; i <= maxMCSIdx; i++)
17796 {
17797 if (sinfo->signal <= rssiMcsTbl[mode][i])
17798 {
17799 maxMCSIdx = i;
17800 break;
17801 }
17802 }
17803 }
17804
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017805 if (rate_flags & eHAL_TX_RATE_VHT80)
17806 {
17807 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17808 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17809 }
17810 else if (rate_flags & eHAL_TX_RATE_VHT40)
17811 {
17812 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17813 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17814 }
17815 else if (rate_flags & eHAL_TX_RATE_VHT20)
17816 {
17817 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17818 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17819 }
17820
Leo Chang6f8870f2013-03-26 18:11:36 -070017821 maxSpeedMCS = 1;
17822 if (currentRate > maxRate)
17823 {
17824 maxRate = currentRate;
17825 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017826
Leo Chang6f8870f2013-03-26 18:11:36 -070017827 }
17828 else
17829#endif /* WLAN_FEATURE_11AC */
17830 {
17831 if (rate_flags & eHAL_TX_RATE_HT40)
17832 {
17833 rateFlag |= 1;
17834 }
17835 if (rate_flags & eHAL_TX_RATE_SGI)
17836 {
17837 rateFlag |= 2;
17838 }
17839
Girish Gowli01abcee2014-07-31 20:18:55 +053017840 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017841 if (rssidx == 1 || rssidx == 2)
17842 {
17843 //get middle rate MCS index if rssi=1/2
17844 for (i=0; i <= 7; i++)
17845 {
17846 if (sinfo->signal <= rssiMcsTbl[mode][i])
17847 {
17848 temp = i+1;
17849 break;
17850 }
17851 }
17852 }
c_hpothu79aab322014-07-14 21:11:01 +053017853
17854 for (i = 0; i < MCSLeng; i++)
17855 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017856 for (j = 0; j < temp; j++)
17857 {
17858 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17859 {
17860 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017861 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017862 break;
17863 }
17864 }
17865 if ((j < temp) && (currentRate > maxRate))
17866 {
17867 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017868 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017869 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017870 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017871 }
17872 }
17873
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017874 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17875 {
17876 maxRate = myRate;
17877 maxSpeedMCS = 1;
17878 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17879 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017880 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017881 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017882 {
17883 maxRate = myRate;
17884 if (rate_flags & eHAL_TX_RATE_LEGACY)
17885 {
17886 maxSpeedMCS = 0;
17887 }
17888 else
17889 {
17890 maxSpeedMCS = 1;
17891 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17892 }
17893 }
17894
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017895 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017896 {
17897 sinfo->txrate.legacy = maxRate;
17898#ifdef LINKSPEED_DEBUG_ENABLED
17899 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17900#endif //LINKSPEED_DEBUG_ENABLED
17901 }
17902 else
17903 {
17904 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017905#ifdef WLAN_FEATURE_11AC
17906 sinfo->txrate.nss = 1;
17907 if (rate_flags & eHAL_TX_RATE_VHT80)
17908 {
17909 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17911 defined(WITH_BACKPORTS)
17912 sinfo->txrate.bw = RATE_INFO_BW_80;
17913#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017914 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017915#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070017916 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017917 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017918 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017919 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017920#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17921 defined(WITH_BACKPORTS)
17922 sinfo->txrate.bw = RATE_INFO_BW_40;
17923#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017924 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017925#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017926 }
17927 else if (rate_flags & eHAL_TX_RATE_VHT20)
17928 {
17929 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17930 }
17931#endif /* WLAN_FEATURE_11AC */
17932 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17933 {
17934 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17935 if (rate_flags & eHAL_TX_RATE_HT40)
17936 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17938 defined(WITH_BACKPORTS)
17939 sinfo->txrate.bw = RATE_INFO_BW_40;
17940#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017941 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017942#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017943 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017944 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017945 if (rate_flags & eHAL_TX_RATE_SGI)
17946 {
17947 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17948 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017949
Jeff Johnson295189b2012-06-20 16:38:30 -070017950#ifdef LINKSPEED_DEBUG_ENABLED
17951 pr_info("Reporting MCS rate %d flags %x\n",
17952 sinfo->txrate.mcs,
17953 sinfo->txrate.flags );
17954#endif //LINKSPEED_DEBUG_ENABLED
17955 }
17956 }
17957 else
17958 {
17959 // report current rate instead of max rate
17960
17961 if (rate_flags & eHAL_TX_RATE_LEGACY)
17962 {
17963 //provide to the UI in units of 100kbps
17964 sinfo->txrate.legacy = myRate;
17965#ifdef LINKSPEED_DEBUG_ENABLED
17966 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17967#endif //LINKSPEED_DEBUG_ENABLED
17968 }
17969 else
17970 {
17971 //must be MCS
17972 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017973#ifdef WLAN_FEATURE_11AC
17974 sinfo->txrate.nss = 1;
17975 if (rate_flags & eHAL_TX_RATE_VHT80)
17976 {
17977 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17978 }
17979 else
17980#endif /* WLAN_FEATURE_11AC */
17981 {
17982 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17983 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017984 if (rate_flags & eHAL_TX_RATE_SGI)
17985 {
17986 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17987 }
17988 if (rate_flags & eHAL_TX_RATE_HT40)
17989 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17991 defined(WITH_BACKPORTS)
17992 sinfo->txrate.bw = RATE_INFO_BW_40;
17993#else
Jeff Johnson295189b2012-06-20 16:38:30 -070017994 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017996 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017997#ifdef WLAN_FEATURE_11AC
17998 else if (rate_flags & eHAL_TX_RATE_VHT80)
17999 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18001 defined(WITH_BACKPORTS)
18002 sinfo->txrate.bw = RATE_INFO_BW_80;
18003#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018004 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018005#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018006 }
18007#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018008#ifdef LINKSPEED_DEBUG_ENABLED
18009 pr_info("Reporting actual MCS rate %d flags %x\n",
18010 sinfo->txrate.mcs,
18011 sinfo->txrate.flags );
18012#endif //LINKSPEED_DEBUG_ENABLED
18013 }
18014 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018015
18016#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18017 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018018 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018019#else
18020 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18021#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018022
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018023 sinfo->tx_packets =
18024 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18025 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18026 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18027 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18028
18029 sinfo->tx_retries =
18030 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18031 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18032 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18033 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18034
18035 sinfo->tx_failed =
18036 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18037 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18038 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18039 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18040
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018041#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18042 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018043 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018044 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018045 STATION_INFO_TX_PACKETS |
18046 STATION_INFO_TX_RETRIES |
18047 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018048#else
18049 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18050 BIT(NL80211_STA_INFO_TX_PACKETS) |
18051 BIT(NL80211_STA_INFO_TX_RETRIES) |
18052 BIT(NL80211_STA_INFO_TX_FAILED);
18053#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018054
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018055 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018056
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018057 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18058 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018059 if (rate_flags & eHAL_TX_RATE_LEGACY)
18060 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18061 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18062 sinfo->rx_packets);
18063 else
18064 hddLog(LOG1,
18065 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18066 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18067 sinfo->tx_packets, sinfo->rx_packets);
18068
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018069 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18070 TRACE_CODE_HDD_CFG80211_GET_STA,
18071 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018072 EXIT();
18073 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018074}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18076static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18077 const u8* mac, struct station_info *sinfo)
18078#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018079static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18080 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018081#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018082{
18083 int ret;
18084
18085 vos_ssr_protect(__func__);
18086 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18087 vos_ssr_unprotect(__func__);
18088
18089 return ret;
18090}
18091
18092static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018093 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018094{
18095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018096 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018097 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018098 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018099
Jeff Johnsone7245742012-09-05 17:12:55 -070018100 ENTER();
18101
Jeff Johnson295189b2012-06-20 16:38:30 -070018102 if (NULL == pAdapter)
18103 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018105 return -ENODEV;
18106 }
18107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18109 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18110 pAdapter->sessionId, timeout));
18111
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018112 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018113 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018114 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018116 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018117 }
18118
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018119 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18120 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18121 (pHddCtx->cfg_ini->fhostArpOffload) &&
18122 (eConnectionState_Associated ==
18123 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18124 {
Amar Singhald53568e2013-09-26 11:03:45 -070018125
18126 hddLog(VOS_TRACE_LEVEL_INFO,
18127 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018128 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018129 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18130 {
18131 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018132 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018133 __func__, vos_status);
18134 }
18135 }
18136
Jeff Johnson295189b2012-06-20 16:38:30 -070018137 /**The get power cmd from the supplicant gets updated by the nl only
18138 *on successful execution of the function call
18139 *we are oppositely mapped w.r.t mode in the driver
18140 **/
18141 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18142
18143 if (VOS_STATUS_E_FAILURE == vos_status)
18144 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18146 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018147 return -EINVAL;
18148 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018149 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018150 return 0;
18151}
18152
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018153static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18154 struct net_device *dev, bool mode, int timeout)
18155{
18156 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018157
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018158 vos_ssr_protect(__func__);
18159 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18160 vos_ssr_unprotect(__func__);
18161
18162 return ret;
18163}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018164
Jeff Johnson295189b2012-06-20 16:38:30 -070018165#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018166static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18167 struct net_device *netdev,
18168 u8 key_index)
18169{
18170 ENTER();
18171 return 0;
18172}
18173
Jeff Johnson295189b2012-06-20 16:38:30 -070018174static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018175 struct net_device *netdev,
18176 u8 key_index)
18177{
18178 int ret;
18179 vos_ssr_protect(__func__);
18180 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18181 vos_ssr_unprotect(__func__);
18182 return ret;
18183}
18184#endif //LINUX_VERSION_CODE
18185
18186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18187static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18188 struct net_device *dev,
18189 struct ieee80211_txq_params *params)
18190{
18191 ENTER();
18192 return 0;
18193}
18194#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18195static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18196 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018197{
Jeff Johnsone7245742012-09-05 17:12:55 -070018198 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018199 return 0;
18200}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018201#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018202
18203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18204static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018205 struct net_device *dev,
18206 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018207{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018208 int ret;
18209
18210 vos_ssr_protect(__func__);
18211 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18212 vos_ssr_unprotect(__func__);
18213 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018214}
18215#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18216static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18217 struct ieee80211_txq_params *params)
18218{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018219 int ret;
18220
18221 vos_ssr_protect(__func__);
18222 ret = __wlan_hdd_set_txq_params(wiphy, params);
18223 vos_ssr_unprotect(__func__);
18224 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018225}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018226#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018227
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018228static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018229 struct net_device *dev,
18230 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018231{
18232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018233 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018234 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018235 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018236 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018237 v_CONTEXT_t pVosContext = NULL;
18238 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018239
Jeff Johnsone7245742012-09-05 17:12:55 -070018240 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018241
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018242 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018243 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018244 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018245 return -EINVAL;
18246 }
18247
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018248 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18249 TRACE_CODE_HDD_CFG80211_DEL_STA,
18250 pAdapter->sessionId, pAdapter->device_mode));
18251
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018252 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18253 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018254 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018255 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018256 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018257 }
18258
Jeff Johnson295189b2012-06-20 16:38:30 -070018259 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018260 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018261 )
18262 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018263 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18264 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18265 if(pSapCtx == NULL){
18266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18267 FL("psapCtx is NULL"));
18268 return -ENOENT;
18269 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018270 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18271 {
18272 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18273 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18274 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18275 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018276 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018277 {
18278 v_U16_t i;
18279 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18280 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018281 if ((pSapCtx->aStaInfo[i].isUsed) &&
18282 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018283 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018284 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018285 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018286 ETHER_ADDR_LEN);
18287
Jeff Johnson295189b2012-06-20 16:38:30 -070018288 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018289 "%s: Delete STA with MAC::"
18290 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018291 __func__,
18292 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18293 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018294 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018295 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018296 }
18297 }
18298 }
18299 else
18300 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018301
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018302 vos_status = hdd_softap_GetStaId(pAdapter,
18303 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018304 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18305 {
18306 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018307 "%s: Skip this DEL STA as this is not used::"
18308 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018309 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018310 return -ENOENT;
18311 }
18312
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018313 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018314 {
18315 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018316 "%s: Skip this DEL STA as deauth is in progress::"
18317 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018318 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018319 return -ENOENT;
18320 }
18321
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018322 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018323
Jeff Johnson295189b2012-06-20 16:38:30 -070018324 hddLog(VOS_TRACE_LEVEL_INFO,
18325 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018326 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018327 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018328 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018329
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018330 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018331 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18332 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018333 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018334 hddLog(VOS_TRACE_LEVEL_INFO,
18335 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018336 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018337 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018338 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018339 return -ENOENT;
18340 }
18341
Jeff Johnson295189b2012-06-20 16:38:30 -070018342 }
18343 }
18344
18345 EXIT();
18346
18347 return 0;
18348}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018349
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018350#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018351int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018352 struct net_device *dev,
18353 struct station_del_parameters *param)
18354#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018356int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018357 struct net_device *dev, const u8 *mac)
18358#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018359int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018360 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018361#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018362#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018363{
18364 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018365 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018366
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018367 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018368
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018369#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018370 if (NULL == param) {
18371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018372 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018373 return -EINVAL;
18374 }
18375
18376 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18377 param->subtype, &delStaParams);
18378
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018379#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018380 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018381 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018382#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018383 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18384
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018385 vos_ssr_unprotect(__func__);
18386
18387 return ret;
18388}
18389
18390static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018391 struct net_device *dev,
18392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18393 const u8 *mac,
18394#else
18395 u8 *mac,
18396#endif
18397 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018398{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018399 hdd_adapter_t *pAdapter;
18400 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018401 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018402#ifdef FEATURE_WLAN_TDLS
18403 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018404
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018405 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018406
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018407 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18408 if (NULL == pAdapter)
18409 {
18410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18411 "%s: Adapter is NULL",__func__);
18412 return -EINVAL;
18413 }
18414 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18415 status = wlan_hdd_validate_context(pHddCtx);
18416 if (0 != status)
18417 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018418 return status;
18419 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018420
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018421 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18422 TRACE_CODE_HDD_CFG80211_ADD_STA,
18423 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018424 mask = params->sta_flags_mask;
18425
18426 set = params->sta_flags_set;
18427
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018429 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18430 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018431
18432 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18433 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018434 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018435 }
18436 }
18437#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018438 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018439 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018440}
18441
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18443static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18444 struct net_device *dev, const u8 *mac,
18445 struct station_parameters *params)
18446#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018447static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18448 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018449#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018450{
18451 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018452
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018453 vos_ssr_protect(__func__);
18454 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18455 vos_ssr_unprotect(__func__);
18456
18457 return ret;
18458}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018459#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018460
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018461static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018462 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018463{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018464 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18465 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018466 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018467 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018468 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018469 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018470
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018471 ENTER();
18472
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018473 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018474 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018475 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018477 return -EINVAL;
18478 }
18479
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018480 if (!pmksa) {
18481 hddLog(LOGE, FL("pmksa is NULL"));
18482 return -EINVAL;
18483 }
18484
18485 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018486 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018487 pmksa->bssid, pmksa->pmkid);
18488 return -EINVAL;
18489 }
18490
18491 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18492 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18493
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18495 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018496 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018497 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018498 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018499 }
18500
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018501 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018502 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18503
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018504 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18505 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018506
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018507 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018508 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018509 &pmk_id, 1, FALSE);
18510
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018511 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18512 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18513 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018515 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018516 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018517}
18518
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018519static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18520 struct cfg80211_pmksa *pmksa)
18521{
18522 int ret;
18523
18524 vos_ssr_protect(__func__);
18525 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18526 vos_ssr_unprotect(__func__);
18527
18528 return ret;
18529}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018530
Wilson Yang6507c4e2013-10-01 20:11:19 -070018531
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018532static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018533 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018534{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18536 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018537 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018538 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018539
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018540 ENTER();
18541
Wilson Yang6507c4e2013-10-01 20:11:19 -070018542 /* Validate pAdapter */
18543 if (NULL == pAdapter)
18544 {
18545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18546 return -EINVAL;
18547 }
18548
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018549 if (!pmksa) {
18550 hddLog(LOGE, FL("pmksa is NULL"));
18551 return -EINVAL;
18552 }
18553
18554 if (!pmksa->bssid) {
18555 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18556 return -EINVAL;
18557 }
18558
Kiet Lam98c46a12014-10-31 15:34:57 -070018559 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18560 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18561
Wilson Yang6507c4e2013-10-01 20:11:19 -070018562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18563 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018564 if (0 != status)
18565 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018566 return status;
18567 }
18568
18569 /*Retrieve halHandle*/
18570 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18571
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18573 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18574 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018575 /* Delete the PMKID CSR cache */
18576 if (eHAL_STATUS_SUCCESS !=
18577 sme_RoamDelPMKIDfromCache(halHandle,
18578 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18579 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18580 MAC_ADDR_ARRAY(pmksa->bssid));
18581 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018582 }
18583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018584 EXIT();
18585 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018586}
18587
Wilson Yang6507c4e2013-10-01 20:11:19 -070018588
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018589static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18590 struct cfg80211_pmksa *pmksa)
18591{
18592 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018593
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018594 vos_ssr_protect(__func__);
18595 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18596 vos_ssr_unprotect(__func__);
18597
18598 return ret;
18599
18600}
18601
18602static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018603{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18605 tHalHandle halHandle;
18606 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018607 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018609 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018610
18611 /* Validate pAdapter */
18612 if (NULL == pAdapter)
18613 {
18614 hddLog(VOS_TRACE_LEVEL_ERROR,
18615 "%s: Invalid Adapter" ,__func__);
18616 return -EINVAL;
18617 }
18618
18619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18620 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018621 if (0 != status)
18622 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018623 return status;
18624 }
18625
18626 /*Retrieve halHandle*/
18627 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18628
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018629 /* Flush the PMKID cache in CSR */
18630 if (eHAL_STATUS_SUCCESS !=
18631 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18633 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018634 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018635 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018636 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018637}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018638
18639static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18640{
18641 int ret;
18642
18643 vos_ssr_protect(__func__);
18644 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18645 vos_ssr_unprotect(__func__);
18646
18647 return ret;
18648}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018649#endif
18650
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018651#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018652static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18653 struct net_device *dev,
18654 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018655{
18656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18657 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018658 hdd_context_t *pHddCtx;
18659 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018660
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018661 ENTER();
18662
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018663 if (NULL == pAdapter)
18664 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018665 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018666 return -ENODEV;
18667 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018668 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18669 ret = wlan_hdd_validate_context(pHddCtx);
18670 if (0 != ret)
18671 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018672 return ret;
18673 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018674 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018675 if (NULL == pHddStaCtx)
18676 {
18677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18678 return -EINVAL;
18679 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018680
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018681 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18682 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18683 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018684 // Added for debug on reception of Re-assoc Req.
18685 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18686 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018687 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018688 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018689 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018690 }
18691
18692#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018693 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018694 ftie->ie_len);
18695#endif
18696
18697 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018698 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18699 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018700 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018701
18702 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018703 return 0;
18704}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018705
18706static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18707 struct net_device *dev,
18708 struct cfg80211_update_ft_ies_params *ftie)
18709{
18710 int ret;
18711
18712 vos_ssr_protect(__func__);
18713 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18714 vos_ssr_unprotect(__func__);
18715
18716 return ret;
18717}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018718#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018719
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018720#ifdef FEATURE_WLAN_SCAN_PNO
18721
18722void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18723 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18724{
18725 int ret;
18726 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18727 hdd_context_t *pHddCtx;
18728
Nirav Shah80830bf2013-12-31 16:35:12 +053018729 ENTER();
18730
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018731 if (NULL == pAdapter)
18732 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018734 "%s: HDD adapter is Null", __func__);
18735 return ;
18736 }
18737
18738 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18739 if (NULL == pHddCtx)
18740 {
18741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18742 "%s: HDD context is Null!!!", __func__);
18743 return ;
18744 }
18745
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018746 spin_lock(&pHddCtx->schedScan_lock);
18747 if (TRUE == pHddCtx->isWiphySuspended)
18748 {
18749 pHddCtx->isSchedScanUpdatePending = TRUE;
18750 spin_unlock(&pHddCtx->schedScan_lock);
18751 hddLog(VOS_TRACE_LEVEL_INFO,
18752 "%s: Update cfg80211 scan database after it resume", __func__);
18753 return ;
18754 }
18755 spin_unlock(&pHddCtx->schedScan_lock);
18756
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018757 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18758
18759 if (0 > ret)
18760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018761 else
18762 {
18763 /* Acquire wakelock to handle the case where APP's tries to suspend
18764 * immediatly after the driver gets connect request(i.e after pno)
18765 * from supplicant, this result in app's is suspending and not able
18766 * to process the connect request to AP */
18767 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18768 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018769 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18771 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018772}
18773
18774/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018775 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018776 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018777 */
18778static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18779{
18780 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18781 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018782 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018783 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18784 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018785
18786 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18787 {
18788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18789 "%s: PNO is allowed only in STA interface", __func__);
18790 return eHAL_STATUS_FAILURE;
18791 }
18792
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018793 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18794
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018795 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018796 * active sessions. PNO is allowed only in case when sap session
18797 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018798 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018799 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18800 {
18801 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018802 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018803
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018804 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18805 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18806 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18807 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018808 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18809 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018810 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018811 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018812 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018813 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018814 }
18815 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18816 pAdapterNode = pNext;
18817 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018818 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018819}
18820
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018821void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18822{
18823 hdd_adapter_t *pAdapter = callbackContext;
18824 hdd_context_t *pHddCtx;
18825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018826 ENTER();
18827
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018828 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18829 {
18830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18831 FL("Invalid adapter or adapter has invalid magic"));
18832 return;
18833 }
18834
18835 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18836 if (0 != wlan_hdd_validate_context(pHddCtx))
18837 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018838 return;
18839 }
18840
c_hpothub53c45d2014-08-18 16:53:14 +053018841 if (VOS_STATUS_SUCCESS != status)
18842 {
18843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018844 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018845 pHddCtx->isPnoEnable = FALSE;
18846 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018847
18848 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18849 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018850 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018851}
18852
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18854 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18855/**
18856 * hdd_config_sched_scan_plan() - configures the sched scan plans
18857 * from the framework.
18858 * @pno_req: pointer to PNO scan request
18859 * @request: pointer to scan request from framework
18860 *
18861 * Return: None
18862 */
18863static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18864 struct cfg80211_sched_scan_request *request,
18865 hdd_context_t *hdd_ctx)
18866{
18867 v_U32_t i = 0;
18868
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018869 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018870 for (i = 0; i < request->n_scan_plans; i++)
18871 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018872 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18873 request->scan_plans[i].iterations;
18874 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18875 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018876 }
18877}
18878#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018879static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018880 struct cfg80211_sched_scan_request *request,
18881 hdd_context_t *hdd_ctx)
18882{
18883 v_U32_t i, temp_int;
18884 /* Driver gets only one time interval which is hardcoded in
18885 * supplicant for 10000ms. Taking power consumption into account 6
18886 * timers will be used, Timervalue is increased exponentially
18887 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18888 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18889 * If it is set to 0 only one timer will be used and PNO scan cycle
18890 * will be repeated after each interval specified by supplicant
18891 * till PNO is disabled.
18892 */
18893 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018894 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018895 HDD_PNO_SCAN_TIMERS_SET_ONE;
18896 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018897 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018898 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18899
18900 temp_int = (request->interval)/1000;
18901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18902 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18903 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018904 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018905 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018906 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018907 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018908 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018909 temp_int *= 2;
18910 }
18911 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018912 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018913}
18914#endif
18915
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018916/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018917 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18918 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018919 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018920static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018921 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18922{
18923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018924 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018925 hdd_context_t *pHddCtx;
18926 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018927 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018928 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18929 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018930 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18931 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018932 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018933 hdd_config_t *pConfig = NULL;
18934 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018935
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018936 ENTER();
18937
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018938 if (NULL == pAdapter)
18939 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018941 "%s: HDD adapter is Null", __func__);
18942 return -ENODEV;
18943 }
18944
18945 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018946 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018947
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018948 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018949 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018950 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018951 }
18952
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018953 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018954 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18955 if (NULL == hHal)
18956 {
18957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18958 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018959 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018960 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18962 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18963 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018964 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018965 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018966 {
18967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18968 "%s: aborting the existing scan is unsuccessfull", __func__);
18969 return -EBUSY;
18970 }
18971
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018972 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018973 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018975 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018976 return -EBUSY;
18977 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018978
c_hpothu37f21312014-04-09 21:49:54 +053018979 if (TRUE == pHddCtx->isPnoEnable)
18980 {
18981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18982 FL("already PNO is enabled"));
18983 return -EBUSY;
18984 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018985
18986 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18987 {
18988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18989 "%s: abort ROC failed ", __func__);
18990 return -EBUSY;
18991 }
18992
c_hpothu37f21312014-04-09 21:49:54 +053018993 pHddCtx->isPnoEnable = TRUE;
18994
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018995 pnoRequest.enable = 1; /*Enable PNO */
18996 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018997
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018998 if (( !pnoRequest.ucNetworksCount ) ||
18999 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019000 {
19001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019002 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019003 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019004 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019005 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019006 goto error;
19007 }
19008
19009 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19010 {
19011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019012 "%s: Incorrect number of channels %d",
19013 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019014 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019015 goto error;
19016 }
19017
19018 /* Framework provides one set of channels(all)
19019 * common for all saved profile */
19020 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19021 channels_allowed, &num_channels_allowed))
19022 {
19023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19024 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019025 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019026 goto error;
19027 }
19028 /* Checking each channel against allowed channel list */
19029 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019030 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019031 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019032 char chList [(request->n_channels*5)+1];
19033 int len;
19034 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019035 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019036 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019037 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019038 if (request->channels[i]->hw_value == channels_allowed[indx])
19039 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019040 if ((!pConfig->enableDFSPnoChnlScan) &&
19041 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19042 {
19043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19044 "%s : Dropping DFS channel : %d",
19045 __func__,channels_allowed[indx]);
19046 num_ignore_dfs_ch++;
19047 break;
19048 }
19049
Nirav Shah80830bf2013-12-31 16:35:12 +053019050 valid_ch[num_ch++] = request->channels[i]->hw_value;
19051 len += snprintf(chList+len, 5, "%d ",
19052 request->channels[i]->hw_value);
19053 break ;
19054 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019055 }
19056 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019057 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019058
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019059 /*If all channels are DFS and dropped, then ignore the PNO request*/
19060 if (num_ignore_dfs_ch == request->n_channels)
19061 {
19062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19063 "%s : All requested channels are DFS channels", __func__);
19064 ret = -EINVAL;
19065 goto error;
19066 }
19067 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019068
19069 pnoRequest.aNetworks =
19070 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19071 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019072 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019073 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19074 FL("failed to allocate memory aNetworks %u"),
19075 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19076 goto error;
19077 }
19078 vos_mem_zero(pnoRequest.aNetworks,
19079 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19080
19081 /* Filling per profile params */
19082 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19083 {
19084 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019085 request->match_sets[i].ssid.ssid_len;
19086
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019087 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19088 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019089 {
19090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019091 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019092 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019093 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019094 goto error;
19095 }
19096
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019097 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019098 request->match_sets[i].ssid.ssid,
19099 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19101 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019102 i, pnoRequest.aNetworks[i].ssId.ssId);
19103 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19104 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19105 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019106
19107 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019108 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19109 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019110
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019111 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019112 }
19113
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019114 for (i = 0; i < request->n_ssids; i++)
19115 {
19116 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019117 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019118 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019119 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019120 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019121 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019122 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019123 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019124 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019125 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019126 break;
19127 }
19128 j++;
19129 }
19130 }
19131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19132 "Number of hidden networks being Configured = %d",
19133 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019135 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019136
19137 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19138 if (pnoRequest.p24GProbeTemplate == NULL)
19139 {
19140 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19141 FL("failed to allocate memory p24GProbeTemplate %u"),
19142 SIR_PNO_MAX_PB_REQ_SIZE);
19143 goto error;
19144 }
19145
19146 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19147 if (pnoRequest.p5GProbeTemplate == NULL)
19148 {
19149 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19150 FL("failed to allocate memory p5GProbeTemplate %u"),
19151 SIR_PNO_MAX_PB_REQ_SIZE);
19152 goto error;
19153 }
19154
19155 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19156 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19157
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019158 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19159 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019160 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019161 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19162 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19163 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019164
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019165 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19166 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19167 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019168 }
19169
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019170 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019171
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019172 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019173
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019174 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019175 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19176 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019177 pAdapter->pno_req_status = 0;
19178
Nirav Shah80830bf2013-12-31 16:35:12 +053019179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19180 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019181 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19182 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019183
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019184 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019185 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019186 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19187 if (eHAL_STATUS_SUCCESS != status)
19188 {
19189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019190 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019191 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019192 goto error;
19193 }
19194
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019195 ret = wait_for_completion_timeout(
19196 &pAdapter->pno_comp_var,
19197 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19198 if (0 >= ret)
19199 {
19200 // Did not receive the response for PNO enable in time.
19201 // Assuming the PNO enable was success.
19202 // Returning error from here, because we timeout, results
19203 // in side effect of Wifi (Wifi Setting) not to work.
19204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19205 FL("Timed out waiting for PNO to be Enabled"));
19206 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019207 }
19208
19209 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019210 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019211
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019212error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19214 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019215 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019216 if (pnoRequest.aNetworks)
19217 vos_mem_free(pnoRequest.aNetworks);
19218 if (pnoRequest.p24GProbeTemplate)
19219 vos_mem_free(pnoRequest.p24GProbeTemplate);
19220 if (pnoRequest.p5GProbeTemplate)
19221 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019222
19223 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019224 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019225}
19226
19227/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019228 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19229 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019230 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019231static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19232 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19233{
19234 int ret;
19235
19236 vos_ssr_protect(__func__);
19237 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19238 vos_ssr_unprotect(__func__);
19239
19240 return ret;
19241}
19242
19243/*
19244 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19245 * Function to disable PNO
19246 */
19247static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019248 struct net_device *dev)
19249{
19250 eHalStatus status = eHAL_STATUS_FAILURE;
19251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19252 hdd_context_t *pHddCtx;
19253 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019254 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019255 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019256
19257 ENTER();
19258
19259 if (NULL == pAdapter)
19260 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019262 "%s: HDD adapter is Null", __func__);
19263 return -ENODEV;
19264 }
19265
19266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019267
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019268 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019269 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019271 "%s: HDD context is Null", __func__);
19272 return -ENODEV;
19273 }
19274
19275 /* The return 0 is intentional when isLogpInProgress and
19276 * isLoadUnloadInProgress. We did observe a crash due to a return of
19277 * failure in sched_scan_stop , especially for a case where the unload
19278 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19279 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19280 * success. If it returns a failure , then its next invocation due to the
19281 * clean up of the second interface will have the dev pointer corresponding
19282 * to the first one leading to a crash.
19283 */
19284 if (pHddCtx->isLogpInProgress)
19285 {
19286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19287 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019288 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019289 return ret;
19290 }
19291
Mihir Shete18156292014-03-11 15:38:30 +053019292 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019293 {
19294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19295 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19296 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019297 }
19298
19299 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19300 if (NULL == hHal)
19301 {
19302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19303 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019304 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019305 }
19306
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019307 pnoRequest.enable = 0; /* Disable PNO */
19308 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019309
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19311 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19312 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019313
19314 INIT_COMPLETION(pAdapter->pno_comp_var);
19315 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19316 pnoRequest.callbackContext = pAdapter;
19317 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019318 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019319 pAdapter->sessionId,
19320 NULL, pAdapter);
19321 if (eHAL_STATUS_SUCCESS != status)
19322 {
19323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19324 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019325 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019326 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019327 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019328 ret = wait_for_completion_timeout(
19329 &pAdapter->pno_comp_var,
19330 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19331 if (0 >= ret)
19332 {
19333 // Did not receive the response for PNO disable in time.
19334 // Assuming the PNO disable was success.
19335 // Returning error from here, because we timeout, results
19336 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019338 FL("Timed out waiting for PNO to be disabled"));
19339 ret = 0;
19340 }
19341
19342 ret = pAdapter->pno_req_status;
19343 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019344
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019345error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019347 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019348
19349 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019350 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019351}
19352
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019353/*
19354 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19355 * NL interface to disable PNO
19356 */
19357static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19358 struct net_device *dev)
19359{
19360 int ret;
19361
19362 vos_ssr_protect(__func__);
19363 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19364 vos_ssr_unprotect(__func__);
19365
19366 return ret;
19367}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019368#endif /*FEATURE_WLAN_SCAN_PNO*/
19369
19370
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019371#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019372#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019373static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19374 struct net_device *dev,
19375 u8 *peer, u8 action_code,
19376 u8 dialog_token,
19377 u16 status_code, u32 peer_capability,
19378 const u8 *buf, size_t len)
19379#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019380#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19381 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019382static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19383 struct net_device *dev,
19384 const u8 *peer, u8 action_code,
19385 u8 dialog_token, u16 status_code,
19386 u32 peer_capability, bool initiator,
19387 const u8 *buf, size_t len)
19388#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19389static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19390 struct net_device *dev,
19391 const u8 *peer, u8 action_code,
19392 u8 dialog_token, u16 status_code,
19393 u32 peer_capability, const u8 *buf,
19394 size_t len)
19395#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19396static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19397 struct net_device *dev,
19398 u8 *peer, u8 action_code,
19399 u8 dialog_token,
19400 u16 status_code, u32 peer_capability,
19401 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019402#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019403static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19404 struct net_device *dev,
19405 u8 *peer, u8 action_code,
19406 u8 dialog_token,
19407 u16 status_code, const u8 *buf,
19408 size_t len)
19409#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019410#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019411{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019412 hdd_adapter_t *pAdapter;
19413 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019414 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019415 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019416 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019417 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019418 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019419 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019420#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019421 u32 peer_capability = 0;
19422#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019423 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019424 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019425 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019426
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019427 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19428 if (NULL == pAdapter)
19429 {
19430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19431 "%s: Adapter is NULL",__func__);
19432 return -EINVAL;
19433 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019434 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19435 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19436 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019437
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019438 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019439 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019442 "Invalid arguments");
19443 return -EINVAL;
19444 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019445
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019446 if (pHddCtx->isLogpInProgress)
19447 {
19448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19449 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019450 wlan_hdd_tdls_set_link_status(pAdapter,
19451 peer,
19452 eTDLS_LINK_IDLE,
19453 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019454 return -EBUSY;
19455 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019456
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019457 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19458 {
19459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19460 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19461 return -EAGAIN;
19462 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019463
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019464 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19465 if (!pHddTdlsCtx) {
19466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19467 "%s: pHddTdlsCtx not valid.", __func__);
19468 }
19469
Hoonki Lee27511902013-03-14 18:19:06 -070019470 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019471 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019473 "%s: TDLS mode is disabled OR not enabled in FW."
19474 MAC_ADDRESS_STR " action %d declined.",
19475 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019476 return -ENOTSUPP;
19477 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019478
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019479 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19480
19481 if( NULL == pHddStaCtx )
19482 {
19483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19484 "%s: HDD station context NULL ",__func__);
19485 return -EINVAL;
19486 }
19487
19488 /* STA should be connected and authenticated
19489 * before sending any TDLS frames
19490 */
19491 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19492 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19493 {
19494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19495 "STA is not connected or unauthenticated. "
19496 "connState %u, uIsAuthenticated %u",
19497 pHddStaCtx->conn_info.connState,
19498 pHddStaCtx->conn_info.uIsAuthenticated);
19499 return -EAGAIN;
19500 }
19501
Hoonki Lee27511902013-03-14 18:19:06 -070019502 /* other than teardown frame, other mgmt frames are not sent if disabled */
19503 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19504 {
19505 /* if tdls_mode is disabled to respond to peer's request */
19506 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19507 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019509 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019510 " TDLS mode is disabled. action %d declined.",
19511 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019512
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019513 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019514 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019515
19516 if (vos_max_concurrent_connections_reached())
19517 {
19518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19519 return -EINVAL;
19520 }
Hoonki Lee27511902013-03-14 18:19:06 -070019521 }
19522
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019523 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19524 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019525 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019526 {
19527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019528 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019529 " TDLS setup is ongoing. action %d declined.",
19530 __func__, MAC_ADDR_ARRAY(peer), action_code);
19531 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019532 }
19533 }
19534
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019535 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19536 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019537 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019538 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19539 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019540 {
19541 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19542 we return error code at 'add_station()'. Hence we have this
19543 check again in addtion to add_station().
19544 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019545 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019546 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19548 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019549 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19550 __func__, MAC_ADDR_ARRAY(peer), action_code,
19551 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019552 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019553 }
19554 else
19555 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019556 /* maximum reached. tweak to send error code to peer and return
19557 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019558 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19560 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019561 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19562 __func__, MAC_ADDR_ARRAY(peer), status_code,
19563 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019564 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019565 /* fall through to send setup resp with failure status
19566 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019567 }
19568 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019569 else
19570 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019571 mutex_lock(&pHddCtx->tdls_lock);
19572 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019573 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019574 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019575 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019577 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19578 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019579 return -EPERM;
19580 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019581 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019582 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019583 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019584
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019586 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019587 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19588 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019589
Hoonki Leea34dd892013-02-05 22:56:02 -080019590 /*Except teardown responder will not be used so just make 0*/
19591 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019592 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019593 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019594
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019595 mutex_lock(&pHddCtx->tdls_lock);
19596 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019597
19598 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19599 responder = pTdlsPeer->is_responder;
19600 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019601 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019603 "%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 -070019604 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19605 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019606 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019607 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019608 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019609 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019610 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019611
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019612 /* Discard TDLS setup if peer is removed by user app */
19613 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19614 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19615 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19616 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19617
19618 mutex_lock(&pHddCtx->tdls_lock);
19619 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19620 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19621 mutex_unlock(&pHddCtx->tdls_lock);
19622 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19623 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19624 MAC_ADDR_ARRAY(peer), action_code);
19625 return -EINVAL;
19626 }
19627 mutex_unlock(&pHddCtx->tdls_lock);
19628 }
19629
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019630 /* For explicit trigger of DIS_REQ come out of BMPS for
19631 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019632 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019633 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019634 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19635 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019636 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019637 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019639 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19640 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019641 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19642 if (status != VOS_STATUS_SUCCESS) {
19643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019644 } else {
19645 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019646 }
Hoonki Lee14621352013-04-16 17:51:19 -070019647 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019648 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019649 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19651 }
19652 }
Hoonki Lee14621352013-04-16 17:51:19 -070019653 }
19654
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019655 /* make sure doesn't call send_mgmt() while it is pending */
19656 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19657 {
19658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019659 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019660 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019661 ret = -EBUSY;
19662 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019663 }
19664
19665 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019666 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19667
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019668 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19669 pAdapter->sessionId, peer, action_code, dialog_token,
19670 status_code, peer_capability, (tANI_U8 *)buf, len,
19671 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019672
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019673 if (VOS_STATUS_SUCCESS != status)
19674 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19676 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019677 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019678 ret = -EINVAL;
19679 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019680 }
19681
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19683 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19684 WAIT_TIME_TDLS_MGMT);
19685
Hoonki Leed37cbb32013-04-20 00:31:14 -070019686 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19687 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19688
19689 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019690 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019692 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019693 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019694 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019695
19696 if (pHddCtx->isLogpInProgress)
19697 {
19698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19699 "%s: LOGP in Progress. Ignore!!!", __func__);
19700 return -EAGAIN;
19701 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019702 if (rc <= 0)
19703 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19704 WLAN_LOG_INDICATOR_HOST_DRIVER,
19705 WLAN_LOG_REASON_HDD_TIME_OUT,
19706 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019707
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019708 ret = -EINVAL;
19709 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019710 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019711 else
19712 {
19713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19714 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19715 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19716 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019717
Gopichand Nakkala05922802013-03-14 12:23:19 -070019718 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019719 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019720 ret = max_sta_failed;
19721 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019722 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019723
Hoonki Leea34dd892013-02-05 22:56:02 -080019724 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19725 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019726 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19728 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019729 }
19730 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19731 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019732 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
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 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019736
19737 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019738
19739tx_failed:
19740 /* add_station will be called before sending TDLS_SETUP_REQ and
19741 * TDLS_SETUP_RSP and as part of add_station driver will enable
19742 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19743 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19744 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19745 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19746 */
19747
19748 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19749 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19750 wlan_hdd_tdls_check_bmps(pAdapter);
19751 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019752}
19753
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019754#if TDLS_MGMT_VERSION2
19755static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19756 u8 *peer, u8 action_code, u8 dialog_token,
19757 u16 status_code, u32 peer_capability,
19758 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019759#else /* TDLS_MGMT_VERSION2 */
19760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19761static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19762 struct net_device *dev,
19763 const u8 *peer, u8 action_code,
19764 u8 dialog_token, u16 status_code,
19765 u32 peer_capability, bool initiator,
19766 const u8 *buf, size_t len)
19767#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19768static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19769 struct net_device *dev,
19770 const u8 *peer, u8 action_code,
19771 u8 dialog_token, u16 status_code,
19772 u32 peer_capability, const u8 *buf,
19773 size_t len)
19774#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19775static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19776 struct net_device *dev,
19777 u8 *peer, u8 action_code,
19778 u8 dialog_token,
19779 u16 status_code, u32 peer_capability,
19780 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019781#else
19782static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19783 u8 *peer, u8 action_code, u8 dialog_token,
19784 u16 status_code, const u8 *buf, size_t len)
19785#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019786#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019787{
19788 int ret;
19789
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019790 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019791#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019792 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19793 dialog_token, status_code,
19794 peer_capability, buf, len);
19795#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19797 defined(WITH_BACKPORTS)
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, initiator,
19801 buf, len);
19802#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19803 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19804 dialog_token, status_code,
19805 peer_capability, buf, len);
19806#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19807 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19808 dialog_token, status_code,
19809 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019810#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019811 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19812 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019813#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019814#endif
19815 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019816
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019817 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019818}
Atul Mittal115287b2014-07-08 13:26:33 +053019819
19820int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019821#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19822 const u8 *peer,
19823#else
Atul Mittal115287b2014-07-08 13:26:33 +053019824 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019825#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019826 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019827 cfg80211_exttdls_callback callback)
19828{
19829
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019830 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019831 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019832 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19834 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19835 __func__, MAC_ADDR_ARRAY(peer));
19836
19837 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19838 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19839
19840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019841 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19842 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19843 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019844 return -ENOTSUPP;
19845 }
19846
19847 /* To cater the requirement of establishing the TDLS link
19848 * irrespective of the data traffic , get an entry of TDLS peer.
19849 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019850 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019851 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19852 if (pTdlsPeer == NULL) {
19853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19854 "%s: peer " MAC_ADDRESS_STR " not existing",
19855 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019856 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019857 return -EINVAL;
19858 }
19859
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019860 /* check FW TDLS Off Channel capability */
19861 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019862 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019863 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019864 {
19865 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19866 pTdlsPeer->peerParams.global_operating_class =
19867 tdls_peer_params->global_operating_class;
19868 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19869 pTdlsPeer->peerParams.min_bandwidth_kbps =
19870 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019871 /* check configured channel is valid, non dfs and
19872 * not current operating channel */
19873 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19874 tdls_peer_params->channel)) &&
19875 (pHddStaCtx) &&
19876 (tdls_peer_params->channel !=
19877 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019878 {
19879 pTdlsPeer->isOffChannelConfigured = TRUE;
19880 }
19881 else
19882 {
19883 pTdlsPeer->isOffChannelConfigured = FALSE;
19884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19885 "%s: Configured Tdls Off Channel is not valid", __func__);
19886
19887 }
19888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019889 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19890 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019891 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019892 pTdlsPeer->isOffChannelConfigured,
19893 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019894 }
19895 else
19896 {
19897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019898 "%s: TDLS off channel FW capability %d, "
19899 "host capab %d or Invalid TDLS Peer Params", __func__,
19900 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19901 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019902 }
19903
Atul Mittal115287b2014-07-08 13:26:33 +053019904 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19905
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019906 mutex_unlock(&pHddCtx->tdls_lock);
19907
Atul Mittal115287b2014-07-08 13:26:33 +053019908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19909 " %s TDLS Add Force Peer Failed",
19910 __func__);
19911 return -EINVAL;
19912 }
19913 /*EXT TDLS*/
19914
19915 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019916 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19918 " %s TDLS set callback Failed",
19919 __func__);
19920 return -EINVAL;
19921 }
19922
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019923 mutex_unlock(&pHddCtx->tdls_lock);
19924
Atul Mittal115287b2014-07-08 13:26:33 +053019925 return(0);
19926
19927}
19928
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019929int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19931 const u8 *peer
19932#else
19933 u8 *peer
19934#endif
19935)
Atul Mittal115287b2014-07-08 13:26:33 +053019936{
19937
19938 hddTdlsPeer_t *pTdlsPeer;
19939 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019940
Atul Mittal115287b2014-07-08 13:26:33 +053019941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19942 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19943 __func__, MAC_ADDR_ARRAY(peer));
19944
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019945 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19947 return -EINVAL;
19948 }
19949
Atul Mittal115287b2014-07-08 13:26:33 +053019950 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19951 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19952
19953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019954 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19955 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19956 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019957 return -ENOTSUPP;
19958 }
19959
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019960 mutex_lock(&pHddCtx->tdls_lock);
19961 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019962
19963 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019964 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019966 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019967 __func__, MAC_ADDR_ARRAY(peer));
19968 return -EINVAL;
19969 }
19970 else {
19971 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19972 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019973 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19974 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019975 /* if channel switch is configured, reset
19976 the channel for this peer */
19977 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19978 {
19979 pTdlsPeer->peerParams.channel = 0;
19980 pTdlsPeer->isOffChannelConfigured = FALSE;
19981 }
Atul Mittal115287b2014-07-08 13:26:33 +053019982 }
19983
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019984 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019985 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019987 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019988 }
Atul Mittal115287b2014-07-08 13:26:33 +053019989
19990 /*EXT TDLS*/
19991
19992 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019993 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19995 " %s TDLS set callback Failed",
19996 __func__);
19997 return -EINVAL;
19998 }
Atul Mittal115287b2014-07-08 13:26:33 +053019999
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020000 mutex_unlock(&pHddCtx->tdls_lock);
20001
20002 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020003}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020004static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20006 const u8 *peer,
20007#else
20008 u8 *peer,
20009#endif
20010 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020011{
20012 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20013 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020014 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020015 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020016
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020017 ENTER();
20018
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020019 if (!pAdapter) {
20020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20021 return -EINVAL;
20022 }
20023
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020024 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20025 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20026 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020027 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020028 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020030 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020031 return -EINVAL;
20032 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020033
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020034 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020035 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020036 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020037 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020038 }
20039
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020040
20041 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020042 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020043 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020045 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20046 "Cannot process TDLS commands",
20047 pHddCtx->cfg_ini->fEnableTDLSSupport,
20048 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020049 return -ENOTSUPP;
20050 }
20051
20052 switch (oper) {
20053 case NL80211_TDLS_ENABLE_LINK:
20054 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020055 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020056 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020057 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20058 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020059 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020060 tANI_U16 numCurrTdlsPeers = 0;
20061 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020062 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020063 tSirMacAddr peerMac;
20064 int channel;
20065 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020066
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20068 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20069 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020070
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020071 mutex_lock(&pHddCtx->tdls_lock);
20072 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020073 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020074 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020075 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20077 " (oper %d) not exsting. ignored",
20078 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20079 return -EINVAL;
20080 }
20081
20082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20083 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20084 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20085 "NL80211_TDLS_ENABLE_LINK");
20086
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020087 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20088 {
20089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20090 MAC_ADDRESS_STR " failed",
20091 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020092 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020093 return -EINVAL;
20094 }
20095
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020096 /* before starting tdls connection, set tdls
20097 * off channel established status to default value */
20098 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020099
20100 mutex_unlock(&pHddCtx->tdls_lock);
20101
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020102 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020103 /* TDLS Off Channel, Disable tdls channel switch,
20104 when there are more than one tdls link */
20105 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020106 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020107 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020108 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020109 /* get connected peer and send disable tdls off chan */
20110 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020111 if ((connPeer) &&
20112 (connPeer->isOffChannelSupported == TRUE) &&
20113 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020114 {
20115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20116 "%s: More then one peer connected, Disable "
20117 "TDLS channel switch", __func__);
20118
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020119 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020120 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20121 channel = connPeer->peerParams.channel;
20122
20123 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020124
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020125 ret = sme_SendTdlsChanSwitchReq(
20126 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020127 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020128 peerMac,
20129 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020130 TDLS_OFF_CHANNEL_BW_OFFSET,
20131 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020132 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020133 hddLog(VOS_TRACE_LEVEL_ERROR,
20134 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020135 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020136 }
20137 else
20138 {
20139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20140 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020141 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020142 "isOffChannelConfigured %d",
20143 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020144 (connPeer ? (connPeer->isOffChannelSupported)
20145 : -1),
20146 (connPeer ? (connPeer->isOffChannelConfigured)
20147 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020148 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020149 }
20150 }
20151
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020152 mutex_lock(&pHddCtx->tdls_lock);
20153 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20154 if ( NULL == pTdlsPeer ) {
20155 mutex_unlock(&pHddCtx->tdls_lock);
20156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20157 "%s: " MAC_ADDRESS_STR
20158 " (oper %d) peer got freed in other context. ignored",
20159 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20160 return -EINVAL;
20161 }
20162 peer_status = pTdlsPeer->link_status;
20163 mutex_unlock(&pHddCtx->tdls_lock);
20164
20165 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020166 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020167 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020168
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020169 if (0 != wlan_hdd_tdls_get_link_establish_params(
20170 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020172 return -EINVAL;
20173 }
20174 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020175
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020176 ret = sme_SendTdlsLinkEstablishParams(
20177 WLAN_HDD_GET_HAL_CTX(pAdapter),
20178 pAdapter->sessionId, peer,
20179 &tdlsLinkEstablishParams);
20180 if (ret != VOS_STATUS_SUCCESS) {
20181 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20182 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020183 /* Send TDLS peer UAPSD capabilities to the firmware and
20184 * register with the TL on after the response for this operation
20185 * is received .
20186 */
20187 ret = wait_for_completion_interruptible_timeout(
20188 &pAdapter->tdls_link_establish_req_comp,
20189 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020190
20191 mutex_lock(&pHddCtx->tdls_lock);
20192 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20193 if ( NULL == pTdlsPeer ) {
20194 mutex_unlock(&pHddCtx->tdls_lock);
20195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20196 "%s %d: " MAC_ADDRESS_STR
20197 " (oper %d) peer got freed in other context. ignored",
20198 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20199 (int)oper);
20200 return -EINVAL;
20201 }
20202 peer_status = pTdlsPeer->link_status;
20203 mutex_unlock(&pHddCtx->tdls_lock);
20204
20205 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020206 {
20207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020208 FL("Link Establish Request Failed Status %ld"),
20209 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020210 return -EINVAL;
20211 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020212 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020213
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020214 mutex_lock(&pHddCtx->tdls_lock);
20215 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20216 if ( NULL == pTdlsPeer ) {
20217 mutex_unlock(&pHddCtx->tdls_lock);
20218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20219 "%s: " MAC_ADDRESS_STR
20220 " (oper %d) peer got freed in other context. ignored",
20221 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20222 return -EINVAL;
20223 }
20224
Atul Mittal115287b2014-07-08 13:26:33 +053020225 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20226 eTDLS_LINK_CONNECTED,
20227 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020228 staDesc.ucSTAId = pTdlsPeer->staId;
20229 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020230
20231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20232 "%s: tdlsLinkEstablishParams of peer "
20233 MAC_ADDRESS_STR "uapsdQueues: %d"
20234 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20235 "isResponder: %d peerstaId: %d",
20236 __func__,
20237 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20238 tdlsLinkEstablishParams.uapsdQueues,
20239 tdlsLinkEstablishParams.qos,
20240 tdlsLinkEstablishParams.maxSp,
20241 tdlsLinkEstablishParams.isBufSta,
20242 tdlsLinkEstablishParams.isOffChannelSupported,
20243 tdlsLinkEstablishParams.isResponder,
20244 pTdlsPeer->staId);
20245
20246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20247 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20248 __func__,
20249 staDesc.ucSTAId,
20250 staDesc.ucQosEnabled);
20251
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020252 ret = WLANTL_UpdateTdlsSTAClient(
20253 pHddCtx->pvosContext,
20254 &staDesc);
20255 if (ret != VOS_STATUS_SUCCESS) {
20256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20257 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020258
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020259 /* Mark TDLS client Authenticated .*/
20260 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20261 pTdlsPeer->staId,
20262 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020263 if (VOS_STATUS_SUCCESS == status)
20264 {
Hoonki Lee14621352013-04-16 17:51:19 -070020265 if (pTdlsPeer->is_responder == 0)
20266 {
20267 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020268 tdlsConnInfo_t *tdlsInfo;
20269
20270 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20271
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020272 if (!vos_timer_is_initialized(
20273 &pTdlsPeer->initiatorWaitTimeoutTimer))
20274 {
20275 /* Initialize initiator wait callback */
20276 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020277 &pTdlsPeer->initiatorWaitTimeoutTimer,
20278 VOS_TIMER_TYPE_SW,
20279 wlan_hdd_tdls_initiator_wait_cb,
20280 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020281 }
Hoonki Lee14621352013-04-16 17:51:19 -070020282 wlan_hdd_tdls_timer_restart(pAdapter,
20283 &pTdlsPeer->initiatorWaitTimeoutTimer,
20284 WAIT_TIME_TDLS_INITIATOR);
20285 /* suspend initiator TX until it receives direct packet from the
20286 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020287 ret = WLANTL_SuspendDataTx(
20288 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20289 &staId, NULL);
20290 if (ret != VOS_STATUS_SUCCESS) {
20291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20292 }
Hoonki Lee14621352013-04-16 17:51:19 -070020293 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020294
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020295 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020296 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020297 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020298 suppChannelLen =
20299 tdlsLinkEstablishParams.supportedChannelsLen;
20300
20301 if ((suppChannelLen > 0) &&
20302 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20303 {
20304 tANI_U8 suppPeerChannel = 0;
20305 int i = 0;
20306 for (i = 0U; i < suppChannelLen; i++)
20307 {
20308 suppPeerChannel =
20309 tdlsLinkEstablishParams.supportedChannels[i];
20310
20311 pTdlsPeer->isOffChannelSupported = FALSE;
20312 if (suppPeerChannel ==
20313 pTdlsPeer->peerParams.channel)
20314 {
20315 pTdlsPeer->isOffChannelSupported = TRUE;
20316 break;
20317 }
20318 }
20319 }
20320 else
20321 {
20322 pTdlsPeer->isOffChannelSupported = FALSE;
20323 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020324 }
20325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20326 "%s: TDLS channel switch request for channel "
20327 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020328 "%d isOffChannelSupported %d", __func__,
20329 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020330 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020331 suppChannelLen,
20332 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020333
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020334 /* TDLS Off Channel, Enable tdls channel switch,
20335 when their is only one tdls link and it supports */
20336 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20337 if ((numCurrTdlsPeers == 1) &&
20338 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20339 (TRUE == pTdlsPeer->isOffChannelConfigured))
20340 {
20341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20342 "%s: Send TDLS channel switch request for channel %d",
20343 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020344
20345 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020346 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20347 channel = pTdlsPeer->peerParams.channel;
20348
20349 mutex_unlock(&pHddCtx->tdls_lock);
20350
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020351 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20352 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020353 peerMac,
20354 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020355 TDLS_OFF_CHANNEL_BW_OFFSET,
20356 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020357 if (ret != VOS_STATUS_SUCCESS) {
20358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20359 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020360 }
20361 else
20362 {
20363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20364 "%s: TDLS channel switch request not sent"
20365 " numCurrTdlsPeers %d "
20366 "isOffChannelSupported %d "
20367 "isOffChannelConfigured %d",
20368 __func__, numCurrTdlsPeers,
20369 pTdlsPeer->isOffChannelSupported,
20370 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020371 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020372 }
20373
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020374 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020375 else
20376 mutex_unlock(&pHddCtx->tdls_lock);
20377
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020378 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020379
20380 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020381 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20382 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020383 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020384 int ac;
20385 uint8 ucAc[4] = { WLANTL_AC_VO,
20386 WLANTL_AC_VI,
20387 WLANTL_AC_BK,
20388 WLANTL_AC_BE };
20389 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20390 for(ac=0; ac < 4; ac++)
20391 {
20392 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20393 pTdlsPeer->staId, ucAc[ac],
20394 tlTid[ac], tlTid[ac], 0, 0,
20395 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020396 if (status != VOS_STATUS_SUCCESS) {
20397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20398 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020399 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020400 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020401 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020402
Bhargav Shah66896792015-10-01 18:17:37 +053020403 /* stop TCP delack timer if TDLS is enable */
20404 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20405 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020406 hdd_wlan_tdls_enable_link_event(peer,
20407 pTdlsPeer->isOffChannelSupported,
20408 pTdlsPeer->isOffChannelConfigured,
20409 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020410 }
20411 break;
20412 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020413 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020414 tANI_U16 numCurrTdlsPeers = 0;
20415 hddTdlsPeer_t *connPeer = NULL;
20416
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20418 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20419 __func__, MAC_ADDR_ARRAY(peer));
20420
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020421 mutex_lock(&pHddCtx->tdls_lock);
20422 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020423
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020424
Sunil Dutt41de4e22013-11-14 18:09:02 +053020425 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020426 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20428 " (oper %d) not exsting. ignored",
20429 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20430 return -EINVAL;
20431 }
20432
20433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20434 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20435 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20436 "NL80211_TDLS_DISABLE_LINK");
20437
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020438 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020439 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020440 long status;
20441
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020442 /* set tdls off channel status to false for this peer */
20443 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020444 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20445 eTDLS_LINK_TEARING,
20446 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20447 eTDLS_LINK_UNSPECIFIED:
20448 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020449 mutex_unlock(&pHddCtx->tdls_lock);
20450
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020451 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20452
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020453 status = sme_DeleteTdlsPeerSta(
20454 WLAN_HDD_GET_HAL_CTX(pAdapter),
20455 pAdapter->sessionId, peer );
20456 if (status != VOS_STATUS_SUCCESS) {
20457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20458 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020459
20460 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20461 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020462
20463 mutex_lock(&pHddCtx->tdls_lock);
20464 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20465 if ( NULL == pTdlsPeer ) {
20466 mutex_unlock(&pHddCtx->tdls_lock);
20467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20468 " peer was freed in other context",
20469 __func__, MAC_ADDR_ARRAY(peer));
20470 return -EINVAL;
20471 }
20472
Atul Mittal271a7652014-09-12 13:18:22 +053020473 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020474 eTDLS_LINK_IDLE,
20475 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020476 mutex_unlock(&pHddCtx->tdls_lock);
20477
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020478 if (status <= 0)
20479 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20481 "%s: Del station failed status %ld",
20482 __func__, status);
20483 return -EPERM;
20484 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020485
20486 /* TDLS Off Channel, Enable tdls channel switch,
20487 when their is only one tdls link and it supports */
20488 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20489 if (numCurrTdlsPeers == 1)
20490 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020491 tSirMacAddr peerMac;
20492 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020493
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020494 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020495 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020496
20497 if (connPeer == NULL) {
20498 mutex_unlock(&pHddCtx->tdls_lock);
20499 hddLog(VOS_TRACE_LEVEL_ERROR,
20500 "%s connPeer is NULL", __func__);
20501 return -EINVAL;
20502 }
20503
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020504 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20505 channel = connPeer->peerParams.channel;
20506
20507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20508 "%s: TDLS channel switch "
20509 "isOffChannelSupported %d "
20510 "isOffChannelConfigured %d "
20511 "isOffChannelEstablished %d",
20512 __func__,
20513 (connPeer ? connPeer->isOffChannelSupported : -1),
20514 (connPeer ? connPeer->isOffChannelConfigured : -1),
20515 (connPeer ? connPeer->isOffChannelEstablished : -1));
20516
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020517 if ((connPeer) &&
20518 (connPeer->isOffChannelSupported == TRUE) &&
20519 (connPeer->isOffChannelConfigured == TRUE))
20520 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020521 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020522 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020523 status = sme_SendTdlsChanSwitchReq(
20524 WLAN_HDD_GET_HAL_CTX(pAdapter),
20525 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020526 peerMac,
20527 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020528 TDLS_OFF_CHANNEL_BW_OFFSET,
20529 TDLS_CHANNEL_SWITCH_ENABLE);
20530 if (status != VOS_STATUS_SUCCESS) {
20531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20532 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020533 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020534 else
20535 mutex_unlock(&pHddCtx->tdls_lock);
20536 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020537 else
20538 {
20539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20540 "%s: TDLS channel switch request not sent "
20541 "numCurrTdlsPeers %d ",
20542 __func__, numCurrTdlsPeers);
20543 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020544 }
20545 else
20546 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020547 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20549 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020550 }
Bhargav Shah66896792015-10-01 18:17:37 +053020551 if (numCurrTdlsPeers == 0) {
20552 /* start TCP delack timer if TDLS is disable */
20553 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20554 hdd_manage_delack_timer(pHddCtx);
20555 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020556 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020557 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020558 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020559 {
Atul Mittal115287b2014-07-08 13:26:33 +053020560 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020561
Atul Mittal115287b2014-07-08 13:26:33 +053020562 if (0 != status)
20563 {
20564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020565 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020566 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020567 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020568 break;
20569 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020570 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020571 {
Atul Mittal115287b2014-07-08 13:26:33 +053020572 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20573 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020574 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020575 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020576
Atul Mittal115287b2014-07-08 13:26:33 +053020577 if (0 != status)
20578 {
20579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020580 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020581 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020582 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020583 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020584 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020585 case NL80211_TDLS_DISCOVERY_REQ:
20586 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020588 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020589 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020590 return -ENOTSUPP;
20591 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20593 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020594 return -ENOTSUPP;
20595 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020596
20597 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020598 return 0;
20599}
Chilam NG571c65a2013-01-19 12:27:36 +053020600
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020601static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020602#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20603 const u8 *peer,
20604#else
20605 u8 *peer,
20606#endif
20607 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020608{
20609 int ret;
20610
20611 vos_ssr_protect(__func__);
20612 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20613 vos_ssr_unprotect(__func__);
20614
20615 return ret;
20616}
20617
Chilam NG571c65a2013-01-19 12:27:36 +053020618int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20619 struct net_device *dev, u8 *peer)
20620{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020621 hddLog(VOS_TRACE_LEVEL_INFO,
20622 "tdls send discover req: "MAC_ADDRESS_STR,
20623 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020624#if TDLS_MGMT_VERSION2
20625 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20626 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20627#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20629 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20630 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20631#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20632 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20633 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20634#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20635 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20636 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20637#else
Chilam NG571c65a2013-01-19 12:27:36 +053020638 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20639 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020640#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020641#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020642}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020643#endif
20644
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020645#ifdef WLAN_FEATURE_GTK_OFFLOAD
20646/*
20647 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20648 * Callback rountine called upon receiving response for
20649 * get offload info
20650 */
20651void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20652 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20653{
20654
20655 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020656 tANI_U8 tempReplayCounter[8];
20657 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020658
20659 ENTER();
20660
20661 if (NULL == pAdapter)
20662 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020664 "%s: HDD adapter is Null", __func__);
20665 return ;
20666 }
20667
20668 if (NULL == pGtkOffloadGetInfoRsp)
20669 {
20670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20671 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20672 return ;
20673 }
20674
20675 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20676 {
20677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20678 "%s: wlan Failed to get replay counter value",
20679 __func__);
20680 return ;
20681 }
20682
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020683 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20684 /* Update replay counter */
20685 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20686 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20687
20688 {
20689 /* changing from little to big endian since supplicant
20690 * works on big endian format
20691 */
20692 int i;
20693 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20694
20695 for (i = 0; i < 8; i++)
20696 {
20697 tempReplayCounter[7-i] = (tANI_U8)p[i];
20698 }
20699 }
20700
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020701 /* Update replay counter to NL */
20702 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020703 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020704}
20705
20706/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020707 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020708 * This function is used to offload GTK rekeying job to the firmware.
20709 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020710int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020711 struct cfg80211_gtk_rekey_data *data)
20712{
20713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20714 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20715 hdd_station_ctx_t *pHddStaCtx;
20716 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020717 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020718 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020719 eHalStatus status = eHAL_STATUS_FAILURE;
20720
20721 ENTER();
20722
20723 if (NULL == pAdapter)
20724 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020726 "%s: HDD adapter is Null", __func__);
20727 return -ENODEV;
20728 }
20729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20731 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20732 pAdapter->sessionId, pAdapter->device_mode));
20733
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020734 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020735 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020737 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020738 }
20739
20740 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20741 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20742 if (NULL == hHal)
20743 {
20744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20745 "%s: HAL context is Null!!!", __func__);
20746 return -EAGAIN;
20747 }
20748
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020749 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20750 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20751 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20752 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020753 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020754 {
20755 /* changing from big to little endian since driver
20756 * works on little endian format
20757 */
20758 tANI_U8 *p =
20759 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20760 int i;
20761
20762 for (i = 0; i < 8; i++)
20763 {
20764 p[7-i] = data->replay_ctr[i];
20765 }
20766 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020767
20768 if (TRUE == pHddCtx->hdd_wlan_suspended)
20769 {
20770 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020771 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20772 sizeof (tSirGtkOffloadParams));
20773 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020774 pAdapter->sessionId);
20775
20776 if (eHAL_STATUS_SUCCESS != status)
20777 {
20778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20779 "%s: sme_SetGTKOffload failed, returned %d",
20780 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020781
20782 /* Need to clear any trace of key value in the memory.
20783 * Thus zero out the memory even though it is local
20784 * variable.
20785 */
20786 vos_mem_zero(&hddGtkOffloadReqParams,
20787 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020788 return status;
20789 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20791 "%s: sme_SetGTKOffload successfull", __func__);
20792 }
20793 else
20794 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20796 "%s: wlan not suspended GTKOffload request is stored",
20797 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020798 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020799
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020800 /* Need to clear any trace of key value in the memory.
20801 * Thus zero out the memory even though it is local
20802 * variable.
20803 */
20804 vos_mem_zero(&hddGtkOffloadReqParams,
20805 sizeof(hddGtkOffloadReqParams));
20806
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020807 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020808 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020809}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020810
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020811int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20812 struct cfg80211_gtk_rekey_data *data)
20813{
20814 int ret;
20815
20816 vos_ssr_protect(__func__);
20817 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20818 vos_ssr_unprotect(__func__);
20819
20820 return ret;
20821}
20822#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020823/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020824 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020825 * This function is used to set access control policy
20826 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020827static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20828 struct net_device *dev,
20829 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020830{
20831 int i;
20832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20833 hdd_hostapd_state_t *pHostapdState;
20834 tsap_Config_t *pConfig;
20835 v_CONTEXT_t pVosContext = NULL;
20836 hdd_context_t *pHddCtx;
20837 int status;
20838
20839 ENTER();
20840
20841 if (NULL == pAdapter)
20842 {
20843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20844 "%s: HDD adapter is Null", __func__);
20845 return -ENODEV;
20846 }
20847
20848 if (NULL == params)
20849 {
20850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20851 "%s: params is Null", __func__);
20852 return -EINVAL;
20853 }
20854
20855 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20856 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020857 if (0 != status)
20858 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020859 return status;
20860 }
20861
20862 pVosContext = pHddCtx->pvosContext;
20863 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20864
20865 if (NULL == pHostapdState)
20866 {
20867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20868 "%s: pHostapdState is Null", __func__);
20869 return -EINVAL;
20870 }
20871
20872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20873 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020874 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20875 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20876 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020877
20878 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20879 {
20880 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20881
20882 /* default value */
20883 pConfig->num_accept_mac = 0;
20884 pConfig->num_deny_mac = 0;
20885
20886 /**
20887 * access control policy
20888 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20889 * listed in hostapd.deny file.
20890 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20891 * listed in hostapd.accept file.
20892 */
20893 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20894 {
20895 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20896 }
20897 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20898 {
20899 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20900 }
20901 else
20902 {
20903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20904 "%s:Acl Policy : %d is not supported",
20905 __func__, params->acl_policy);
20906 return -ENOTSUPP;
20907 }
20908
20909 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20910 {
20911 pConfig->num_accept_mac = params->n_acl_entries;
20912 for (i = 0; i < params->n_acl_entries; i++)
20913 {
20914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20915 "** Add ACL MAC entry %i in WhiletList :"
20916 MAC_ADDRESS_STR, i,
20917 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20918
20919 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20920 sizeof(qcmacaddr));
20921 }
20922 }
20923 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20924 {
20925 pConfig->num_deny_mac = params->n_acl_entries;
20926 for (i = 0; i < params->n_acl_entries; i++)
20927 {
20928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20929 "** Add ACL MAC entry %i in BlackList :"
20930 MAC_ADDRESS_STR, i,
20931 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20932
20933 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20934 sizeof(qcmacaddr));
20935 }
20936 }
20937
20938 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20939 {
20940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20941 "%s: SAP Set Mac Acl fail", __func__);
20942 return -EINVAL;
20943 }
20944 }
20945 else
20946 {
20947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020948 "%s: Invalid device_mode = %s (%d)",
20949 __func__, hdd_device_modetoString(pAdapter->device_mode),
20950 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020951 return -EINVAL;
20952 }
20953
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020954 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020955 return 0;
20956}
20957
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020958static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20959 struct net_device *dev,
20960 const struct cfg80211_acl_data *params)
20961{
20962 int ret;
20963 vos_ssr_protect(__func__);
20964 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20965 vos_ssr_unprotect(__func__);
20966
20967 return ret;
20968}
20969
Leo Chang9056f462013-08-01 19:21:11 -070020970#ifdef WLAN_NL80211_TESTMODE
20971#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020972void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020973(
20974 void *pAdapter,
20975 void *indCont
20976)
20977{
Leo Changd9df8aa2013-09-26 13:32:26 -070020978 tSirLPHBInd *lphbInd;
20979 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020980 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020981
20982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020983 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020984
c_hpothu73f35e62014-04-18 13:40:08 +053020985 if (pAdapter == NULL)
20986 {
20987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20988 "%s: pAdapter is NULL\n",__func__);
20989 return;
20990 }
20991
Leo Chang9056f462013-08-01 19:21:11 -070020992 if (NULL == indCont)
20993 {
20994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020995 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020996 return;
20997 }
20998
c_hpothu73f35e62014-04-18 13:40:08 +053020999 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021000 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021001 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021002 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021003 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021004 GFP_ATOMIC);
21005 if (!skb)
21006 {
21007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21008 "LPHB timeout, NL buffer alloc fail");
21009 return;
21010 }
21011
Leo Changac3ba772013-10-07 09:47:04 -070021012 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021013 {
21014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21015 "WLAN_HDD_TM_ATTR_CMD put fail");
21016 goto nla_put_failure;
21017 }
Leo Changac3ba772013-10-07 09:47:04 -070021018 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021019 {
21020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21021 "WLAN_HDD_TM_ATTR_TYPE put fail");
21022 goto nla_put_failure;
21023 }
Leo Changac3ba772013-10-07 09:47:04 -070021024 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021025 sizeof(tSirLPHBInd), lphbInd))
21026 {
21027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21028 "WLAN_HDD_TM_ATTR_DATA put fail");
21029 goto nla_put_failure;
21030 }
Leo Chang9056f462013-08-01 19:21:11 -070021031 cfg80211_testmode_event(skb, GFP_ATOMIC);
21032 return;
21033
21034nla_put_failure:
21035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21036 "NLA Put fail");
21037 kfree_skb(skb);
21038
21039 return;
21040}
21041#endif /* FEATURE_WLAN_LPHB */
21042
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021043static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021044{
21045 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21046 int err = 0;
21047#ifdef FEATURE_WLAN_LPHB
21048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021049 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021050
21051 ENTER();
21052
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021053 err = wlan_hdd_validate_context(pHddCtx);
21054 if (0 != err)
21055 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021056 return err;
21057 }
Leo Chang9056f462013-08-01 19:21:11 -070021058#endif /* FEATURE_WLAN_LPHB */
21059
21060 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21061 if (err)
21062 {
21063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21064 "%s Testmode INV ATTR", __func__);
21065 return err;
21066 }
21067
21068 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21069 {
21070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21071 "%s Testmode INV CMD", __func__);
21072 return -EINVAL;
21073 }
21074
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21076 TRACE_CODE_HDD_CFG80211_TESTMODE,
21077 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021078 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21079 {
21080#ifdef FEATURE_WLAN_LPHB
21081 /* Low Power Heartbeat configuration request */
21082 case WLAN_HDD_TM_CMD_WLAN_HB:
21083 {
21084 int buf_len;
21085 void *buf;
21086 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021087 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021088
21089 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21090 {
21091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21092 "%s Testmode INV DATA", __func__);
21093 return -EINVAL;
21094 }
21095
21096 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21097 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021098
Manjeet Singh3c577442017-02-10 19:03:38 +053021099 if (buf_len > sizeof(*hb_params)) {
21100 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21101 buf_len);
21102 return -ERANGE;
21103 }
21104
Amar Singhal05852702014-02-04 14:40:00 -080021105 hb_params_temp =(tSirLPHBReq *)buf;
21106 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21107 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21108 return -EINVAL;
21109
Leo Chang9056f462013-08-01 19:21:11 -070021110 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21111 if (NULL == hb_params)
21112 {
21113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21114 "%s Request Buffer Alloc Fail", __func__);
21115 return -EINVAL;
21116 }
21117
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021118 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021119 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021120 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21121 hb_params,
21122 wlan_hdd_cfg80211_lphb_ind_handler);
21123 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021124 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21126 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021127 vos_mem_free(hb_params);
21128 }
Leo Chang9056f462013-08-01 19:21:11 -070021129 return 0;
21130 }
21131#endif /* FEATURE_WLAN_LPHB */
21132 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21134 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021135 return -EOPNOTSUPP;
21136 }
21137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021138 EXIT();
21139 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021140}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021141
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021142static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21143#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21144 struct wireless_dev *wdev,
21145#endif
21146 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021147{
21148 int ret;
21149
21150 vos_ssr_protect(__func__);
21151 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21152 vos_ssr_unprotect(__func__);
21153
21154 return ret;
21155}
Leo Chang9056f462013-08-01 19:21:11 -070021156#endif /* CONFIG_NL80211_TESTMODE */
21157
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021158extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021159static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021160 struct net_device *dev,
21161 int idx, struct survey_info *survey)
21162{
21163 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21164 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021165 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021166 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021167 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021168 v_S7_t snr,rssi;
21169 int status, i, j, filled = 0;
21170
21171 ENTER();
21172
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021173 if (NULL == pAdapter)
21174 {
21175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21176 "%s: HDD adapter is Null", __func__);
21177 return -ENODEV;
21178 }
21179
21180 if (NULL == wiphy)
21181 {
21182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21183 "%s: wiphy is Null", __func__);
21184 return -ENODEV;
21185 }
21186
21187 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21188 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021189 if (0 != status)
21190 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021191 return status;
21192 }
21193
Mihir Sheted9072e02013-08-21 17:02:29 +053021194 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21195
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021196 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021197 0 != pAdapter->survey_idx ||
21198 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021199 {
21200 /* The survey dump ops when implemented completely is expected to
21201 * return a survey of all channels and the ops is called by the
21202 * kernel with incremental values of the argument 'idx' till it
21203 * returns -ENONET. But we can only support the survey for the
21204 * operating channel for now. survey_idx is used to track
21205 * that the ops is called only once and then return -ENONET for
21206 * the next iteration
21207 */
21208 pAdapter->survey_idx = 0;
21209 return -ENONET;
21210 }
21211
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021212 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21213 {
21214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21215 "%s: Roaming in progress, hence return ", __func__);
21216 return -ENONET;
21217 }
21218
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021219 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21220
21221 wlan_hdd_get_snr(pAdapter, &snr);
21222 wlan_hdd_get_rssi(pAdapter, &rssi);
21223
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21225 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21226 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021227 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21228 hdd_wlan_get_freq(channel, &freq);
21229
21230
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021231 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021232 {
21233 if (NULL == wiphy->bands[i])
21234 {
21235 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21236 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21237 continue;
21238 }
21239
21240 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21241 {
21242 struct ieee80211_supported_band *band = wiphy->bands[i];
21243
21244 if (band->channels[j].center_freq == (v_U16_t)freq)
21245 {
21246 survey->channel = &band->channels[j];
21247 /* The Rx BDs contain SNR values in dB for the received frames
21248 * while the supplicant expects noise. So we calculate and
21249 * return the value of noise (dBm)
21250 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21251 */
21252 survey->noise = rssi - snr;
21253 survey->filled = SURVEY_INFO_NOISE_DBM;
21254 filled = 1;
21255 }
21256 }
21257 }
21258
21259 if (filled)
21260 pAdapter->survey_idx = 1;
21261 else
21262 {
21263 pAdapter->survey_idx = 0;
21264 return -ENONET;
21265 }
21266
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021267 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021268 return 0;
21269}
21270
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021271static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21272 struct net_device *dev,
21273 int idx, struct survey_info *survey)
21274{
21275 int ret;
21276
21277 vos_ssr_protect(__func__);
21278 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21279 vos_ssr_unprotect(__func__);
21280
21281 return ret;
21282}
21283
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021284/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021285 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021286 * this is called when cfg80211 driver resume
21287 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21288 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021289int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021290{
21291 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21292 hdd_adapter_t *pAdapter;
21293 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21294 VOS_STATUS status = VOS_STATUS_SUCCESS;
21295
21296 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021297
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021298 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021299 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021300 return 0;
21301 }
21302
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021303 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21304 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021305
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021306 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021307 {
21308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21309 "%s: Resume SoftAP", __func__);
21310 hdd_set_wlan_suspend_mode(false);
21311 }
21312
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021313 spin_lock(&pHddCtx->schedScan_lock);
21314 pHddCtx->isWiphySuspended = FALSE;
21315 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21316 {
21317 spin_unlock(&pHddCtx->schedScan_lock);
21318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21319 "%s: Return resume is not due to PNO indication", __func__);
21320 return 0;
21321 }
21322 // Reset flag to avoid updatating cfg80211 data old results again
21323 pHddCtx->isSchedScanUpdatePending = FALSE;
21324 spin_unlock(&pHddCtx->schedScan_lock);
21325
21326 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21327
21328 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21329 {
21330 pAdapter = pAdapterNode->pAdapter;
21331 if ( (NULL != pAdapter) &&
21332 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21333 {
21334 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021335 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21337 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021338 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021339 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021340 {
21341 /* Acquire wakelock to handle the case where APP's tries to
21342 * suspend immediately after updating the scan results. Whis
21343 * results in app's is in suspended state and not able to
21344 * process the connect request to AP
21345 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021346 hdd_prevent_suspend_timeout(2000,
21347 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021348 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021349 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021350
21351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21352 "%s : cfg80211 scan result database updated", __func__);
21353
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021354 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021355 return 0;
21356
21357 }
21358 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21359 pAdapterNode = pNext;
21360 }
21361
21362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21363 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021364 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021365 return 0;
21366}
21367
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021368int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21369{
21370 int ret;
21371
21372 vos_ssr_protect(__func__);
21373 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21374 vos_ssr_unprotect(__func__);
21375
21376 return ret;
21377}
21378
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021379/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021380 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021381 * this is called when cfg80211 driver suspends
21382 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021383int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021384 struct cfg80211_wowlan *wow)
21385{
21386 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021387 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021388
21389 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021390
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021391 ret = wlan_hdd_validate_context(pHddCtx);
21392 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021393 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021394 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021395 }
21396
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021397 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21399 "%s: Suspend SoftAP", __func__);
21400 hdd_set_wlan_suspend_mode(true);
21401 }
21402
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021403
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021404 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21405 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21406 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021407 pHddCtx->isWiphySuspended = TRUE;
21408
21409 EXIT();
21410
21411 return 0;
21412}
21413
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021414int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21415 struct cfg80211_wowlan *wow)
21416{
21417 int ret;
21418
21419 vos_ssr_protect(__func__);
21420 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21421 vos_ssr_unprotect(__func__);
21422
21423 return ret;
21424}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021425
21426#ifdef FEATURE_OEM_DATA_SUPPORT
21427static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021428 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021429{
21430 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21431
21432 ENTER();
21433
21434 if (wlan_hdd_validate_context(pHddCtx)) {
21435 return;
21436 }
21437 if (!pMsg)
21438 {
21439 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21440 return;
21441 }
21442
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021443 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021444
21445 EXIT();
21446 return;
21447
21448}
21449
21450void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021451 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021452{
21453 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21454
21455 ENTER();
21456
21457 if (wlan_hdd_validate_context(pHddCtx)) {
21458 return;
21459 }
21460
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021462
21463 switch(evType) {
21464 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021465 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021466 break;
21467 default:
21468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21469 break;
21470 }
21471 EXIT();
21472}
21473#endif
21474
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021475#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21476 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021477/**
21478 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21479 * @wiphy: Pointer to wiphy
21480 * @wdev: Pointer to wireless device structure
21481 *
21482 * This function is used to abort an ongoing scan
21483 *
21484 * Return: None
21485 */
21486static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21487 struct wireless_dev *wdev)
21488{
21489 struct net_device *dev = wdev->netdev;
21490 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21491 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21492 int ret;
21493
21494 ENTER();
21495
21496 if (NULL == adapter) {
21497 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21498 return;
21499 }
21500
21501 ret = wlan_hdd_validate_context(hdd_ctx);
21502 if (0 != ret)
21503 return;
21504
21505 wlan_hdd_scan_abort(adapter);
21506
21507 return;
21508}
21509
21510/**
21511 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21512 * @wiphy: Pointer to wiphy
21513 * @wdev: Pointer to wireless device structure
21514 *
21515 * Return: None
21516 */
21517void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21518 struct wireless_dev *wdev)
21519{
21520 vos_ssr_protect(__func__);
21521 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21522 vos_ssr_unprotect(__func__);
21523
21524 return;
21525}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021526#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021527
Abhishek Singh936c6932017-11-07 17:28:23 +053021528#ifdef CHANNEL_SWITCH_SUPPORTED
21529/**
21530 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21531 * channel in SAP/GO
21532 * @wiphy: wiphy pointer
21533 * @dev: dev pointer.
21534 * @csa_params: Change channel params
21535 *
21536 * This function is called to switch channel in SAP/GO
21537 *
21538 * Return: 0 if success else return non zero
21539 */
21540static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21541 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21542{
21543 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21544 hdd_context_t *hdd_ctx;
21545 uint8_t channel;
21546 int ret;
21547 v_CONTEXT_t vos_ctx;
21548
21549 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21550
21551 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21552 ret = wlan_hdd_validate_context(hdd_ctx);
21553 if (ret)
21554 return ret;
21555
21556 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21557 if (!vos_ctx) {
21558 hddLog(LOGE, FL("Vos ctx is null"));
21559 return -EINVAL;
21560 }
21561
21562 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21563 (WLAN_HDD_P2P_GO != adapter->device_mode))
21564 return -ENOTSUPP;
21565
21566 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021567 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021568
21569 return ret;
21570}
21571
21572/**
21573 * wlan_hdd_cfg80211_channel_switch()- function to switch
21574 * channel in SAP/GO
21575 * @wiphy: wiphy pointer
21576 * @dev: dev pointer.
21577 * @csa_params: Change channel params
21578 *
21579 * This function is called to switch channel in SAP/GO
21580 *
21581 * Return: 0 if success else return non zero
21582 */
21583static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21584 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21585{
21586 int ret;
21587
21588 vos_ssr_protect(__func__);
21589 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21590 vos_ssr_unprotect(__func__);
21591
21592 return ret;
21593}
21594#endif
21595
Jeff Johnson295189b2012-06-20 16:38:30 -070021596/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021597static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021598{
21599 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21600 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21601 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21602 .change_station = wlan_hdd_change_station,
21603#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21604 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21605 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21606 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021607#else
21608 .start_ap = wlan_hdd_cfg80211_start_ap,
21609 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21610 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021611#endif
21612 .change_bss = wlan_hdd_cfg80211_change_bss,
21613 .add_key = wlan_hdd_cfg80211_add_key,
21614 .get_key = wlan_hdd_cfg80211_get_key,
21615 .del_key = wlan_hdd_cfg80211_del_key,
21616 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021617#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021618 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021619#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021620 .scan = wlan_hdd_cfg80211_scan,
21621 .connect = wlan_hdd_cfg80211_connect,
21622 .disconnect = wlan_hdd_cfg80211_disconnect,
21623 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21624 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21625 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21626 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21627 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021628 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21629 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021630 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21632 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21633 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21634 .set_txq_params = wlan_hdd_set_txq_params,
21635#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021636 .get_station = wlan_hdd_cfg80211_get_station,
21637 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21638 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021639 .add_station = wlan_hdd_cfg80211_add_station,
21640#ifdef FEATURE_WLAN_LFR
21641 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21642 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21643 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21644#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021645#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21646 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21647#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021648#ifdef FEATURE_WLAN_TDLS
21649 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21650 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21651#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021652#ifdef WLAN_FEATURE_GTK_OFFLOAD
21653 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21654#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021655#ifdef FEATURE_WLAN_SCAN_PNO
21656 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21657 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21658#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021659 .resume = wlan_hdd_cfg80211_resume_wlan,
21660 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021661 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021662#ifdef WLAN_NL80211_TESTMODE
21663 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21664#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021665 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21667 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021668 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021669#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021670#ifdef CHANNEL_SWITCH_SUPPORTED
21671 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21672#endif
21673
Jeff Johnson295189b2012-06-20 16:38:30 -070021674};
21675