blob: d70b5e33c03b80ff56e974ff7654b9e4802866fd [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
Abhinav Kumar1ac5cb42018-09-21 16:11:03 +0530307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
308 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
314};
315
Jeff Johnson295189b2012-06-20 16:38:30 -0700316static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
317{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530318 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530320 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 .bitrates = a_mode_rates,
322 .n_bitrates = a_mode_rates_size,
323 .ht_cap.ht_supported = 1,
324 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
325 | IEEE80211_HT_CAP_GRN_FLD
326 | IEEE80211_HT_CAP_DSSSCCK40
327 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
328 | IEEE80211_HT_CAP_SGI_40
329 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
330 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
331 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
332 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
333 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
334 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
335};
336
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530337/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 TX/RX direction for each kind of interface */
339static const struct ieee80211_txrx_stypes
340wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
341 [NL80211_IFTYPE_STATION] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ACTION) |
344 BIT(SIR_MAC_MGMT_PROBE_REQ),
345 },
346 [NL80211_IFTYPE_AP] = {
347 .tx = 0xffff,
348 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
350 BIT(SIR_MAC_MGMT_PROBE_REQ) |
351 BIT(SIR_MAC_MGMT_DISASSOC) |
352 BIT(SIR_MAC_MGMT_AUTH) |
353 BIT(SIR_MAC_MGMT_DEAUTH) |
354 BIT(SIR_MAC_MGMT_ACTION),
355 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700356 [NL80211_IFTYPE_ADHOC] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_PROBE_REQ) |
361 BIT(SIR_MAC_MGMT_DISASSOC) |
362 BIT(SIR_MAC_MGMT_AUTH) |
363 BIT(SIR_MAC_MGMT_DEAUTH) |
364 BIT(SIR_MAC_MGMT_ACTION),
365 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 [NL80211_IFTYPE_P2P_CLIENT] = {
367 .tx = 0xffff,
368 .rx = BIT(SIR_MAC_MGMT_ACTION) |
369 BIT(SIR_MAC_MGMT_PROBE_REQ),
370 },
371 [NL80211_IFTYPE_P2P_GO] = {
372 /* This is also same as for SoftAP */
373 .tx = 0xffff,
374 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ) |
377 BIT(SIR_MAC_MGMT_DISASSOC) |
378 BIT(SIR_MAC_MGMT_AUTH) |
379 BIT(SIR_MAC_MGMT_DEAUTH) |
380 BIT(SIR_MAC_MGMT_ACTION),
381 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700382};
383
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800385static const struct ieee80211_iface_limit
386wlan_hdd_iface_limit[] = {
387 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800388 /* max = 3 ; Our driver create two interfaces during driver init
389 * wlan0 and p2p0 interfaces. p2p0 is considered as station
390 * interface until a group is formed. In JB architecture, once the
391 * group is formed, interface type of p2p0 is changed to P2P GO or
392 * Client.
393 * When supplicant remove the group, it first issue a set interface
394 * cmd to change the mode back to Station. In JB this works fine as
395 * we advertize two station type interface during driver init.
396 * Some vendors create separate interface for P2P GO/Client,
397 * after group formation(Third one). But while group remove
398 * supplicant first tries to change the mode(3rd interface) to STATION
399 * But as we advertized only two sta type interfaces nl80211 was
400 * returning error for the third one which was leading to failure in
401 * delete interface. Ideally while removing the group, supplicant
402 * should not try to change the 3rd interface mode to Station type.
403 * Till we get a fix in wpa_supplicant, we advertize max STA
404 * interface type to 3
405 */
406 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800407 .types = BIT(NL80211_IFTYPE_STATION),
408 },
409 {
410 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700411 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800412 },
413 {
414 .max = 1,
415 .types = BIT(NL80211_IFTYPE_P2P_GO) |
416 BIT(NL80211_IFTYPE_P2P_CLIENT),
417 },
418};
419
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530420/* interface limits for sta + monitor SCC */
421static const struct ieee80211_iface_limit
422wlan_hdd_iface_sta_mon_limit[] = {
423 {
424 .max = 1,
425 .types = BIT(NL80211_IFTYPE_STATION),
426 },
427 {
428 .max = 1, /* Monitor interface */
429 .types = BIT(NL80211_IFTYPE_MONITOR),
430 },
431};
432
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800433/* By default, only single channel concurrency is allowed */
434static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530435wlan_hdd_iface_combination[] = {
436 {
437 .limits = wlan_hdd_iface_limit,
438 .num_different_channels = 1,
439 /*
440 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
441 * and p2p0 interfaces during driver init
442 * Some vendors create separate interface for P2P operations.
443 * wlan0: STA interface
444 * p2p0: P2P Device interface, action frames goes
445 * through this interface.
446 * p2p-xx: P2P interface, After GO negotiation this interface is
447 * created for p2p operations(GO/CLIENT interface).
448 */
449 .max_interfaces = WLAN_MAX_INTERFACES,
450 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
451 .beacon_int_infra_match = false,
452 },
453 {
454 .limits = wlan_hdd_iface_sta_mon_limit,
455 .num_different_channels = 1,
456 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
457 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
458 .beacon_int_infra_match = false,
459 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800460};
461#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800462
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
464static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +0530465 .flags = WIPHY_WOWLAN_ANY |
466 WIPHY_WOWLAN_MAGIC_PKT,
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530467 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
468 .pattern_min_len = 1,
469 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
470};
471#endif
472
Jeff Johnson295189b2012-06-20 16:38:30 -0700473static struct cfg80211_ops wlan_hdd_cfg80211_ops;
474
475/* Data rate 100KBPS based on IE Index */
476struct index_data_rate_type
477{
478 v_U8_t beacon_rate_index;
479 v_U16_t supported_rate[4];
480};
481
482/* 11B, 11G Rate table include Basic rate and Extended rate
483 The IDX field is the rate index
484 The HI field is the rate when RSSI is strong or being ignored
485 (in this case we report actual rate)
486 The MID field is the rate when RSSI is moderate
487 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
488 The LO field is the rate when RSSI is low
489 (in this case we don't report rates, actual current rate used)
490 */
491static const struct
492{
493 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700494 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700495} supported_data_rate[] =
496{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700497/* IDX HI HM LM LO (RSSI-based index */
498 {2, { 10, 10, 10, 0}},
499 {4, { 20, 20, 10, 0}},
500 {11, { 55, 20, 10, 0}},
501 {12, { 60, 55, 20, 0}},
502 {18, { 90, 55, 20, 0}},
503 {22, {110, 55, 20, 0}},
504 {24, {120, 90, 60, 0}},
505 {36, {180, 120, 60, 0}},
506 {44, {220, 180, 60, 0}},
507 {48, {240, 180, 90, 0}},
508 {66, {330, 180, 90, 0}},
509 {72, {360, 240, 90, 0}},
510 {96, {480, 240, 120, 0}},
511 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700512};
513
514/* MCS Based rate table */
515static struct index_data_rate_type supported_mcs_rate[] =
516{
517/* MCS L20 L40 S20 S40 */
518 {0, {65, 135, 72, 150}},
519 {1, {130, 270, 144, 300}},
520 {2, {195, 405, 217, 450}},
521 {3, {260, 540, 289, 600}},
522 {4, {390, 810, 433, 900}},
523 {5, {520, 1080, 578, 1200}},
524 {6, {585, 1215, 650, 1350}},
525 {7, {650, 1350, 722, 1500}}
526};
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528#ifdef WLAN_FEATURE_11AC
529
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530530#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700531
532struct index_vht_data_rate_type
533{
534 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530535 v_U16_t supported_VHT80_rate[2];
536 v_U16_t supported_VHT40_rate[2];
537 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700538};
539
540typedef enum
541{
542 DATA_RATE_11AC_MAX_MCS_7,
543 DATA_RATE_11AC_MAX_MCS_8,
544 DATA_RATE_11AC_MAX_MCS_9,
545 DATA_RATE_11AC_MAX_MCS_NA
546} eDataRate11ACMaxMcs;
547
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530548/* SSID broadcast type */
549typedef enum eSSIDBcastType
550{
551 eBCAST_UNKNOWN = 0,
552 eBCAST_NORMAL = 1,
553 eBCAST_HIDDEN = 2,
554} tSSIDBcastType;
555
Leo Chang6f8870f2013-03-26 18:11:36 -0700556/* MCS Based VHT rate table */
557static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
558{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530559/* MCS L80 S80 L40 S40 L20 S40*/
560 {0, {293, 325}, {135, 150}, {65, 72}},
561 {1, {585, 650}, {270, 300}, {130, 144}},
562 {2, {878, 975}, {405, 450}, {195, 217}},
563 {3, {1170, 1300}, {540, 600}, {260, 289}},
564 {4, {1755, 1950}, {810, 900}, {390, 433}},
565 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
566 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
567 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
568 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
569 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700570};
571#endif /* WLAN_FEATURE_11AC */
572
c_hpothu79aab322014-07-14 21:11:01 +0530573/*array index points to MCS and array value points respective rssi*/
574static int rssiMcsTbl[][10] =
575{
576/*MCS 0 1 2 3 4 5 6 7 8 9*/
577 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
578 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
579 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
580};
581
Jeff Johnson295189b2012-06-20 16:38:30 -0700582extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530583#ifdef FEATURE_WLAN_SCAN_PNO
584static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
585#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700586
Leo Chang9056f462013-08-01 19:21:11 -0700587#ifdef WLAN_NL80211_TESTMODE
588enum wlan_hdd_tm_attr
589{
590 WLAN_HDD_TM_ATTR_INVALID = 0,
591 WLAN_HDD_TM_ATTR_CMD = 1,
592 WLAN_HDD_TM_ATTR_DATA = 2,
593 WLAN_HDD_TM_ATTR_TYPE = 3,
594 /* keep last */
595 WLAN_HDD_TM_ATTR_AFTER_LAST,
596 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
597};
598
599enum wlan_hdd_tm_cmd
600{
601 WLAN_HDD_TM_CMD_WLAN_HB = 1,
602};
603
604#define WLAN_HDD_TM_DATA_MAX_LEN 5000
605
606static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
607{
608 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
609 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
610 .len = WLAN_HDD_TM_DATA_MAX_LEN },
611};
612#endif /* WLAN_NL80211_TESTMODE */
613
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614#ifdef FEATURE_WLAN_CH_AVOID
615/*
616 * FUNCTION: wlan_hdd_send_avoid_freq_event
617 * This is called when wlan driver needs to send vendor specific
618 * avoid frequency range event to userspace
619 */
620int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
621 tHddAvoidFreqList *pAvoidFreqList)
622{
623 struct sk_buff *vendor_event;
624
625 ENTER();
626
627 if (!pHddCtx)
628 {
629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
630 "%s: HDD context is null", __func__);
631 return -1;
632 }
633
634 if (!pAvoidFreqList)
635 {
636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
637 "%s: pAvoidFreqList is null", __func__);
638 return -1;
639 }
640
641 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
643 NULL,
644#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800645 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530646 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800647 GFP_KERNEL);
648 if (!vendor_event)
649 {
650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
651 "%s: cfg80211_vendor_event_alloc failed", __func__);
652 return -1;
653 }
654
655 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
656 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
657
658 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
659
660 EXIT();
661 return 0;
662}
663#endif /* FEATURE_WLAN_CH_AVOID */
664
Srinivas Dasari030bad32015-02-18 23:23:54 +0530665/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530666 * define short names for the global vendor params
667 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
668 */
669#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
670
671/**
672 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
673 * hang reason
674 * @reason: cds recovery reason
675 *
676 * Return: Vendor specific reason code
677 */
678static enum qca_wlan_vendor_hang_reason
679hdd_convert_hang_reason(enum vos_hang_reason reason)
680{
681 unsigned int ret_val;
682
683 switch (reason) {
684 case VOS_GET_MSG_BUFF_FAILURE:
685 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
686 break;
687 case VOS_ACTIVE_LIST_TIMEOUT:
688 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
689 break;
690 case VOS_SCAN_REQ_EXPIRED:
691 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
692 break;
693 case VOS_TRANSMISSIONS_TIMEOUT:
694 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
695 break;
696 case VOS_DXE_FAILURE:
697 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
698 break;
699 case VOS_WDI_FAILURE:
700 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
701 break;
702 case VOS_REASON_UNSPECIFIED:
703 default:
704 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
705 }
706 return ret_val;
707}
708
709/**
710 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
711 * @hdd_ctx: Pointer to hdd context
712 * @reason: cds recovery reason
713 *
714 * Return: 0 on success or failure reason
715 */
716int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
717 enum vos_hang_reason reason)
718{
719 struct sk_buff *vendor_event;
720 enum qca_wlan_vendor_hang_reason hang_reason;
721
722 ENTER();
723
724 if (!hdd_ctx) {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "HDD context is null");
727 return -EINVAL;
728 }
729
730 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
732 NULL,
733#endif
734 sizeof(unsigned int),
735 HANG_REASON_INDEX,
736 GFP_KERNEL);
737 if (!vendor_event) {
738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
739 "cfg80211_vendor_event_alloc failed");
740 return -ENOMEM;
741 }
742
743 hang_reason = hdd_convert_hang_reason(reason);
744
745 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
746 (unsigned int) hang_reason)) {
747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
748 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
749 kfree_skb(vendor_event);
750 return -EINVAL;
751 }
752
753 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
754
755 EXIT();
756 return 0;
757}
758#undef HANG_REASON_INDEX
759
760/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530761 * FUNCTION: __wlan_hdd_cfg80211_nan_request
762 * This is called when wlan driver needs to send vendor specific
763 * nan request event.
764 */
765static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
766 struct wireless_dev *wdev,
767 const void *data, int data_len)
768{
769 tNanRequestReq nan_req;
770 VOS_STATUS status;
771 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530772 struct net_device *dev = wdev->netdev;
773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
774 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
776
777 if (0 == data_len)
778 {
779 hddLog(VOS_TRACE_LEVEL_ERROR,
780 FL("NAN - Invalid Request, length = 0"));
781 return ret_val;
782 }
783
784 if (NULL == data)
785 {
786 hddLog(VOS_TRACE_LEVEL_ERROR,
787 FL("NAN - Invalid Request, data is NULL"));
788 return ret_val;
789 }
790
791 status = wlan_hdd_validate_context(pHddCtx);
792 if (0 != status)
793 {
794 hddLog(VOS_TRACE_LEVEL_ERROR,
795 FL("HDD context is not valid"));
796 return -EINVAL;
797 }
798
799 hddLog(LOG1, FL("Received NAN command"));
800 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
801 (tANI_U8 *)data, data_len);
802
803 /* check the NAN Capability */
804 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
805 {
806 hddLog(VOS_TRACE_LEVEL_ERROR,
807 FL("NAN is not supported by Firmware"));
808 return -EINVAL;
809 }
810
811 nan_req.request_data_len = data_len;
812 nan_req.request_data = data;
813
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530814 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530815 if (VOS_STATUS_SUCCESS == status)
816 {
817 ret_val = 0;
818 }
819 return ret_val;
820}
821
822/*
823 * FUNCTION: wlan_hdd_cfg80211_nan_request
824 * Wrapper to protect the nan vendor command from ssr
825 */
826static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
827 struct wireless_dev *wdev,
828 const void *data, int data_len)
829{
830 int ret;
831
832 vos_ssr_protect(__func__);
833 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
834 vos_ssr_unprotect(__func__);
835
836 return ret;
837}
838
839/*
840 * FUNCTION: wlan_hdd_cfg80211_nan_callback
841 * This is a callback function and it gets called
842 * when we need to report nan response event to
843 * upper layers.
844 */
845static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
846{
847 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
848 struct sk_buff *vendor_event;
849 int status;
850 tSirNanEvent *data;
851
852 ENTER();
853 if (NULL == msg)
854 {
855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
856 FL(" msg received here is null"));
857 return;
858 }
859 data = msg;
860
861 status = wlan_hdd_validate_context(pHddCtx);
862
863 if (0 != status)
864 {
865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
866 FL("HDD context is not valid"));
867 return;
868 }
869
870 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
872 NULL,
873#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530874 data->event_data_len +
875 NLMSG_HDRLEN,
876 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
877 GFP_KERNEL);
878
879 if (!vendor_event)
880 {
881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
882 FL("cfg80211_vendor_event_alloc failed"));
883 return;
884 }
885 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
886 data->event_data_len, data->event_data))
887 {
888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
889 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
890 kfree_skb(vendor_event);
891 return;
892 }
893 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
894 EXIT();
895}
896
897/*
898 * FUNCTION: wlan_hdd_cfg80211_nan_init
899 * This function is called to register the callback to sme layer
900 */
901inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
902{
903 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
904}
905
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530906/*
907 * define short names for the global vendor params
908 * used by __wlan_hdd_cfg80211_get_station_cmd()
909 */
910#define STATION_INVALID \
911 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
912#define STATION_INFO \
913 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
914#define STATION_ASSOC_FAIL_REASON \
915 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530916#define STATION_REMOTE \
917 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530918#define STATION_MAX \
919 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
920
921static const struct nla_policy
922hdd_get_station_policy[STATION_MAX + 1] = {
923 [STATION_INFO] = {.type = NLA_FLAG},
924 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
925};
926
927/**
928 * hdd_get_station_assoc_fail() - Handle get station assoc fail
929 * @hdd_ctx: HDD context within host driver
930 * @wdev: wireless device
931 *
932 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
933 * Validate cmd attributes and send the station info to upper layers.
934 *
935 * Return: Success(0) or reason code for failure
936 */
937static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
938 hdd_adapter_t *adapter)
939{
940 struct sk_buff *skb = NULL;
941 uint32_t nl_buf_len;
942 hdd_station_ctx_t *hdd_sta_ctx;
943
944 nl_buf_len = NLMSG_HDRLEN;
945 nl_buf_len += sizeof(uint32_t);
946 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
947
948 if (!skb) {
949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
950 return -ENOMEM;
951 }
952
953 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
954
955 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
956 hdd_sta_ctx->conn_info.assoc_status_code)) {
957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
958 goto fail;
959 }
960 return cfg80211_vendor_cmd_reply(skb);
961fail:
962 if (skb)
963 kfree_skb(skb);
964 return -EINVAL;
965}
966
967/**
968 * hdd_map_auth_type() - transform auth type specific to
969 * vendor command
970 * @auth_type: csr auth type
971 *
972 * Return: Success(0) or reason code for failure
973 */
974static int hdd_convert_auth_type(uint32_t auth_type)
975{
976 uint32_t ret_val;
977
978 switch (auth_type) {
979 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
980 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
981 break;
982 case eCSR_AUTH_TYPE_SHARED_KEY:
983 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
984 break;
985 case eCSR_AUTH_TYPE_WPA:
986 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
987 break;
988 case eCSR_AUTH_TYPE_WPA_PSK:
989 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
990 break;
991 case eCSR_AUTH_TYPE_AUTOSWITCH:
992 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
993 break;
994 case eCSR_AUTH_TYPE_WPA_NONE:
995 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
996 break;
997 case eCSR_AUTH_TYPE_RSN:
998 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
999 break;
1000 case eCSR_AUTH_TYPE_RSN_PSK:
1001 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1002 break;
1003 case eCSR_AUTH_TYPE_FT_RSN:
1004 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1005 break;
1006 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1007 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1008 break;
1009 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1010 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1011 break;
1012 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1013 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1014 break;
1015#ifdef FEATURE_WLAN_ESE
1016 case eCSR_AUTH_TYPE_CCKM_WPA:
1017 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1018 break;
1019 case eCSR_AUTH_TYPE_CCKM_RSN:
1020 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1021 break;
1022#endif
1023 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1024 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1025 break;
1026 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1027 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1028 break;
1029 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1030 case eCSR_AUTH_TYPE_FAILED:
1031 case eCSR_AUTH_TYPE_NONE:
1032 default:
1033 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1034 break;
1035 }
1036 return ret_val;
1037}
1038
1039/**
1040 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1041 * vendor command
1042 * @dot11mode: dot11mode
1043 *
1044 * Return: Success(0) or reason code for failure
1045 */
1046static int hdd_convert_dot11mode(uint32_t dot11mode)
1047{
1048 uint32_t ret_val;
1049
1050 switch (dot11mode) {
1051 case eCSR_CFG_DOT11_MODE_11A:
1052 ret_val = QCA_WLAN_802_11_MODE_11A;
1053 break;
1054 case eCSR_CFG_DOT11_MODE_11B:
1055 ret_val = QCA_WLAN_802_11_MODE_11B;
1056 break;
1057 case eCSR_CFG_DOT11_MODE_11G:
1058 ret_val = QCA_WLAN_802_11_MODE_11G;
1059 break;
1060 case eCSR_CFG_DOT11_MODE_11N:
1061 ret_val = QCA_WLAN_802_11_MODE_11N;
1062 break;
1063 case eCSR_CFG_DOT11_MODE_11AC:
1064 ret_val = QCA_WLAN_802_11_MODE_11AC;
1065 break;
1066 case eCSR_CFG_DOT11_MODE_AUTO:
1067 case eCSR_CFG_DOT11_MODE_ABG:
1068 default:
1069 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1070 }
1071 return ret_val;
1072}
1073
1074/**
1075 * hdd_add_tx_bitrate() - add tx bitrate attribute
1076 * @skb: pointer to sk buff
1077 * @hdd_sta_ctx: pointer to hdd station context
1078 * @idx: attribute index
1079 *
1080 * Return: Success(0) or reason code for failure
1081 */
1082static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1083 hdd_station_ctx_t *hdd_sta_ctx,
1084 int idx)
1085{
1086 struct nlattr *nla_attr;
1087 uint32_t bitrate, bitrate_compat;
1088
1089 nla_attr = nla_nest_start(skb, idx);
1090 if (!nla_attr)
1091 goto fail;
1092 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301093 bitrate = cfg80211_calculate_bitrate(
1094 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301095
1096 /* report 16-bit bitrate only if we can */
1097 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1098 if (bitrate > 0 &&
1099 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1101 goto fail;
1102 }
1103 if (bitrate_compat > 0 &&
1104 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1106 goto fail;
1107 }
1108 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301109 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1111 goto fail;
1112 }
1113 nla_nest_end(skb, nla_attr);
1114 return 0;
1115fail:
1116 return -EINVAL;
1117}
1118
1119/**
1120 * hdd_add_sta_info() - add station info attribute
1121 * @skb: pointer to sk buff
1122 * @hdd_sta_ctx: pointer to hdd station context
1123 * @idx: attribute index
1124 *
1125 * Return: Success(0) or reason code for failure
1126 */
1127static int32_t hdd_add_sta_info(struct sk_buff *skb,
1128 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1129{
1130 struct nlattr *nla_attr;
1131
1132 nla_attr = nla_nest_start(skb, idx);
1133 if (!nla_attr)
1134 goto fail;
1135 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301136 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1138 goto fail;
1139 }
1140 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1141 goto fail;
1142 nla_nest_end(skb, nla_attr);
1143 return 0;
1144fail:
1145 return -EINVAL;
1146}
1147
1148/**
1149 * hdd_add_survey_info() - add survey info attribute
1150 * @skb: pointer to sk buff
1151 * @hdd_sta_ctx: pointer to hdd station context
1152 * @idx: attribute index
1153 *
1154 * Return: Success(0) or reason code for failure
1155 */
1156static int32_t hdd_add_survey_info(struct sk_buff *skb,
1157 hdd_station_ctx_t *hdd_sta_ctx,
1158 int idx)
1159{
1160 struct nlattr *nla_attr;
1161
1162 nla_attr = nla_nest_start(skb, idx);
1163 if (!nla_attr)
1164 goto fail;
1165 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301166 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301167 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301168 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1170 goto fail;
1171 }
1172 nla_nest_end(skb, nla_attr);
1173 return 0;
1174fail:
1175 return -EINVAL;
1176}
1177
1178/**
1179 * hdd_add_link_standard_info() - add link info attribute
1180 * @skb: pointer to sk buff
1181 * @hdd_sta_ctx: pointer to hdd station context
1182 * @idx: attribute index
1183 *
1184 * Return: Success(0) or reason code for failure
1185 */
1186static int32_t
1187hdd_add_link_standard_info(struct sk_buff *skb,
1188 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1189{
1190 struct nlattr *nla_attr;
1191
1192 nla_attr = nla_nest_start(skb, idx);
1193 if (!nla_attr)
1194 goto fail;
1195 if (nla_put(skb,
1196 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301197 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1198 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1200 goto fail;
1201 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301202 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1203 hdd_sta_ctx->cache_conn_info.bssId))
1204 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301205 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1206 goto fail;
1207 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1208 goto fail;
1209 nla_nest_end(skb, nla_attr);
1210 return 0;
1211fail:
1212 return -EINVAL;
1213}
1214
1215/**
1216 * hdd_add_ap_standard_info() - add ap info attribute
1217 * @skb: pointer to sk buff
1218 * @hdd_sta_ctx: pointer to hdd station context
1219 * @idx: attribute index
1220 *
1221 * Return: Success(0) or reason code for failure
1222 */
1223static int32_t
1224hdd_add_ap_standard_info(struct sk_buff *skb,
1225 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1226{
1227 struct nlattr *nla_attr;
1228
1229 nla_attr = nla_nest_start(skb, idx);
1230 if (!nla_attr)
1231 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301232 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301233 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301234 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1235 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1237 goto fail;
1238 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301239 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301240 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301241 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1242 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1244 goto fail;
1245 }
1246 nla_nest_end(skb, nla_attr);
1247 return 0;
1248fail:
1249 return -EINVAL;
1250}
1251
1252/**
1253 * hdd_get_station_info() - send BSS information to supplicant
1254 * @hdd_ctx: pointer to hdd context
1255 * @adapter: pointer to adapter
1256 *
1257 * Return: 0 if success else error status
1258 */
1259static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1260 hdd_adapter_t *adapter)
1261{
1262 struct sk_buff *skb = NULL;
1263 uint8_t *tmp_hs20 = NULL;
1264 uint32_t nl_buf_len;
1265 hdd_station_ctx_t *hdd_sta_ctx;
1266
1267 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1268
1269 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301270
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1272 VOS_MAC_ADDR_SIZE +
1273 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1274 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1275 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301276 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301277 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1279 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1280 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1281 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1284 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1285 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1286 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1287 cache_conn_info.hs20vendor_ie);
1288 nl_buf_len +=
1289 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301290 1);
1291 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301292 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1293 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1294 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1295 nl_buf_len +=
1296 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301297
1298
1299 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1300 if (!skb) {
1301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1302 __func__, __LINE__);
1303 return -ENOMEM;
1304 }
1305
1306 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1307 LINK_INFO_STANDARD_NL80211_ATTR)) {
1308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1309 goto fail;
1310 }
1311 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1312 AP_INFO_STANDARD_NL80211_ATTR)) {
1313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
1316 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301317 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301318 nla_put_u32(skb, INFO_AKM,
1319 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301320 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301321 nla_put_u32(skb, WLAN802_11_MODE,
1322 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1325 goto fail;
1326 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301327 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301329 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1330 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1332 goto fail;
1333 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301334 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301336 (sizeof(hdd_sta_ctx->
1337 cache_conn_info.vht_operation)),
1338 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1340 goto fail;
1341 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301342 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301343 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301344 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1345 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1347 goto fail;
1348 }
1349
1350 return cfg80211_vendor_cmd_reply(skb);
1351fail:
1352 if (skb)
1353 kfree_skb(skb);
1354 return -EINVAL;
1355}
1356
1357/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301358 * hdd_add_survey_info_sap_get_len - get data length used in
1359 * hdd_add_survey_info_sap()
1360 *
1361 * This function calculates the data length used in hdd_add_survey_info_sap()
1362 *
1363 * Return: total data length used in hdd_add_survey_info_sap()
1364 */
1365static uint32_t hdd_add_survey_info_sap_get_len(void)
1366{
1367 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1368}
1369
1370/**
1371 * hdd_add_survey_info - add survey info attribute
1372 * @skb: pointer to response skb buffer
1373 * @stainfo: station information
1374 * @idx: attribute type index for nla_next_start()
1375 *
1376 * This function adds survey info attribute to response skb buffer
1377 *
1378 * Return : 0 on success and errno on failure
1379 */
1380static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1381 struct hdd_cache_sta_info *stainfo,
1382 int idx)
1383{
1384 struct nlattr *nla_attr;
1385
1386 nla_attr = nla_nest_start(skb, idx);
1387 if (!nla_attr)
1388 goto fail;
1389 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1390 stainfo->freq)) {
1391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1392 FL("put fail"));
1393 goto fail;
1394 }
1395 nla_nest_end(skb, nla_attr);
1396 return 0;
1397fail:
1398 return -EINVAL;
1399}
1400
1401/**
1402 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1403 * hdd_add_tx_bitrate_sap()
1404 *
1405 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1406 *
1407 * Return: total data length used in hdd_add_tx_bitrate_sap()
1408 */
1409static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1410{
1411 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1412}
1413
1414/**
1415 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1416 * @skb: pointer to response skb buffer
1417 * @stainfo: station information
1418 * @idx: attribute type index for nla_next_start()
1419 *
1420 * This function adds vht nss attribute to response skb buffer
1421 *
1422 * Return : 0 on success and errno on failure
1423 */
1424static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1425 struct hdd_cache_sta_info *stainfo,
1426 int idx)
1427{
1428 struct nlattr *nla_attr;
1429
1430 nla_attr = nla_nest_start(skb, idx);
1431 if (!nla_attr)
1432 goto fail;
1433
1434 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1435 stainfo->nss)) {
1436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1437 FL("put fail"));
1438 goto fail;
1439 }
1440 nla_nest_end(skb, nla_attr);
1441 return 0;
1442fail:
1443 return -EINVAL;
1444}
1445
1446/**
1447 * hdd_add_sta_info_sap_get_len - get data length used in
1448 * hdd_add_sta_info_sap()
1449 *
1450 * This function calculates the data length used in hdd_add_sta_info_sap()
1451 *
1452 * Return: total data length used in hdd_add_sta_info_sap()
1453 */
1454static uint32_t hdd_add_sta_info_sap_get_len(void)
1455{
1456 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1457 hdd_add_tx_bitrate_sap_get_len());
1458}
1459
1460/**
1461 * hdd_add_sta_info_sap - add sta signal info attribute
1462 * @skb: pointer to response skb buffer
1463 * @rssi: peer rssi value
1464 * @stainfo: station information
1465 * @idx: attribute type index for nla_next_start()
1466 *
1467 * This function adds sta signal attribute to response skb buffer
1468 *
1469 * Return : 0 on success and errno on failure
1470 */
1471static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1472 struct hdd_cache_sta_info *stainfo, int idx)
1473{
1474 struct nlattr *nla_attr;
1475
1476 nla_attr = nla_nest_start(skb, idx);
1477 if (!nla_attr)
1478 goto fail;
1479
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301480 /* upperlayer expects positive rssi value */
1481 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1483 FL("put fail"));
1484 goto fail;
1485 }
1486 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1488 FL("put fail"));
1489 goto fail;
1490 }
1491
1492 nla_nest_end(skb, nla_attr);
1493 return 0;
1494fail:
1495 return -EINVAL;
1496}
1497
1498/**
1499 * hdd_add_link_standard_info_sap_get_len - get data length used in
1500 * hdd_add_link_standard_info_sap()
1501 *
1502 * This function calculates the data length used in
1503 * hdd_add_link_standard_info_sap()
1504 *
1505 * Return: total data length used in hdd_add_link_standard_info_sap()
1506 */
1507static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1508{
1509 return ((NLA_HDRLEN) +
1510 hdd_add_survey_info_sap_get_len() +
1511 hdd_add_sta_info_sap_get_len() +
1512 (sizeof(uint32_t) + NLA_HDRLEN));
1513}
1514
1515/**
1516 * hdd_add_link_standard_info_sap - add add link info attribut
1517 * @skb: pointer to response skb buffer
1518 * @stainfo: station information
1519 * @idx: attribute type index for nla_next_start()
1520 *
1521 * This function adds link info attribut to response skb buffer
1522 *
1523 * Return : 0 on success and errno on failure
1524 */
1525static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1526 struct hdd_cache_sta_info *stainfo,
1527 int idx)
1528{
1529 struct nlattr *nla_attr;
1530
1531 nla_attr = nla_nest_start(skb, idx);
1532 if (!nla_attr)
1533 goto fail;
1534 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1535 goto fail;
1536 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1537 goto fail;
1538
1539 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1541 FL("put fail"));
1542 goto fail;
1543 }
1544
1545 nla_nest_end(skb, nla_attr);
1546 return 0;
1547fail:
1548 return -EINVAL;
1549}
1550
1551/**
1552 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1553 * hdd_add_ap_standard_info_sap()
1554 * @stainfo: station information
1555 *
1556 * This function calculates the data length used in
1557 * hdd_add_ap_standard_info_sap()
1558 *
1559 * Return: total data length used in hdd_add_ap_standard_info_sap()
1560 */
1561static uint32_t hdd_add_ap_standard_info_sap_get_len(
1562 struct hdd_cache_sta_info *stainfo)
1563{
1564 uint32_t len;
1565
1566 len = NLA_HDRLEN;
1567 if (stainfo->vht_present)
1568 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1569 if (stainfo->ht_present)
1570 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1571
1572 return len;
1573}
1574
1575/**
1576 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1577 * @skb: pointer to response skb buffer
1578 * @stainfo: station information
1579 * @idx: attribute type index for nla_next_start()
1580 *
1581 * This function adds HT and VHT info attributes to response skb buffer
1582 *
1583 * Return : 0 on success and errno on failure
1584 */
1585static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1586 struct hdd_cache_sta_info *stainfo,
1587 int idx)
1588{
1589 struct nlattr *nla_attr;
1590
1591 nla_attr = nla_nest_start(skb, idx);
1592 if (!nla_attr)
1593 goto fail;
1594
1595 if (stainfo->vht_present) {
1596 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1597 sizeof(stainfo->vht_caps),
1598 &stainfo->vht_caps)) {
1599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1600 FL("put fail"));
1601 goto fail;
1602 }
1603 }
1604 if (stainfo->ht_present) {
1605 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1606 sizeof(stainfo->ht_caps),
1607 &stainfo->ht_caps)) {
1608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1609 FL("put fail"));
1610 goto fail;
1611 }
1612 }
1613 nla_nest_end(skb, nla_attr);
1614 return 0;
1615fail:
1616 return -EINVAL;
1617}
1618
1619/**
1620 * hdd_decode_ch_width - decode channel band width based
1621 * @ch_width: encoded enum value holding channel band width
1622 *
1623 * This function decodes channel band width from the given encoded enum value.
1624 *
1625 * Returns: decoded channel band width.
1626 */
1627static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1628{
1629 switch (ch_width) {
1630 case 0:
1631 return 20;
1632 case 1:
1633 return 40;
1634 case 2:
1635 return 80;
1636 default:
1637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1638 "invalid enum: %d", ch_width);
1639 return 20;
1640 }
1641}
1642
1643/**
1644 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1645 * @hdd_ctx: hdd context
1646 * @adapter: hostapd interface
1647 * @mac_addr: mac address of requested peer
1648 *
1649 * This function collect and indicate the cached(deleted) peer's info
1650 *
1651 * Return: 0 on success, otherwise error value
1652 */
1653static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1654 hdd_adapter_t *adapter,
1655 v_MACADDR_t mac_addr)
1656{
1657 struct hdd_cache_sta_info *stainfo;
1658 struct sk_buff *skb = NULL;
1659 uint32_t nl_buf_len;
1660 uint8_t cw;
1661 ptSapContext sap_ctx;
1662 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1663
1664 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1665 if(sap_ctx == NULL){
1666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1667 FL("psapCtx is NULL"));
1668 return -ENOENT;
1669 }
1670
1671 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1672 mac_addr.bytes);
1673 if (!stainfo) {
1674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1675 "peer " MAC_ADDRESS_STR " not found",
1676 MAC_ADDR_ARRAY(mac_addr.bytes));
1677 return -EINVAL;
1678 }
1679 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1681 "peer " MAC_ADDRESS_STR " is in connected state",
1682 MAC_ADDR_ARRAY(mac_addr.bytes));
1683 return -EINVAL;
1684 }
1685
1686
1687 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1688 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1689 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1690 (sizeof(cw) + NLA_HDRLEN) +
1691 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1692
1693 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1694 if (!skb) {
1695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1696 return -ENOMEM;
1697 }
1698
1699 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1700 LINK_INFO_STANDARD_NL80211_ATTR)) {
1701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1702 goto fail;
1703 }
1704
1705 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1706 AP_INFO_STANDARD_NL80211_ATTR)) {
1707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1708 goto fail;
1709 }
1710
1711 /* upper layer expects decoded channel BW */
1712 cw = hdd_decode_ch_width(stainfo->ch_width);
1713 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1714 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1716 goto fail;
1717 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301718 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1720 goto fail;
1721 }
1722
1723 vos_mem_zero(stainfo, sizeof(*stainfo));
1724
1725 return cfg80211_vendor_cmd_reply(skb);
1726fail:
1727 if (skb)
1728 kfree_skb(skb);
1729
1730 return -EINVAL;
1731}
1732
1733/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301734 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1735 * @wiphy: corestack handler
1736 * @wdev: wireless device
1737 * @data: data
1738 * @data_len: data length
1739 *
1740 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1741 * Validate cmd attributes and send the station info to upper layers.
1742 *
1743 * Return: Success(0) or reason code for failure
1744 */
1745static int32_t
1746__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1747 struct wireless_dev *wdev,
1748 const void *data,
1749 int data_len)
1750{
1751 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1752 struct net_device *dev = wdev->netdev;
1753 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1754 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1755 int32_t status;
1756
1757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1758 if (VOS_FTM_MODE == hdd_get_conparam()) {
1759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1760 status = -EPERM;
1761 goto out;
1762 }
1763
1764 status = wlan_hdd_validate_context(hdd_ctx);
1765 if (0 != status)
1766 goto out;
1767
1768
1769 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1770 data, data_len, NULL);
1771 if (status) {
1772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1773 goto out;
1774 }
1775
1776 /* Parse and fetch Command Type*/
1777 if (tb[STATION_INFO]) {
1778 status = hdd_get_station_info(hdd_ctx, adapter);
1779 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1780 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301781 } else if (tb[STATION_REMOTE]) {
1782 v_MACADDR_t mac_addr;
1783
1784 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1785 adapter->device_mode != WLAN_HDD_P2P_GO) {
1786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1787 adapter->device_mode);
1788 status = -EINVAL;
1789 goto out;
1790 }
1791
1792 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1793 VOS_MAC_ADDRESS_LEN);
1794
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1796 MAC_ADDR_ARRAY(mac_addr.bytes));
1797
1798 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1799 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301800 } else {
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1802 status = -EINVAL;
1803 goto out;
1804 }
1805 EXIT();
1806out:
1807 return status;
1808}
1809
1810/**
1811 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1812 * @wiphy: corestack handler
1813 * @wdev: wireless device
1814 * @data: data
1815 * @data_len: data length
1816 *
1817 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1818 * Validate cmd attributes and send the station info to upper layers.
1819 *
1820 * Return: Success(0) or reason code for failure
1821 */
1822static int32_t
1823hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1824 struct wireless_dev *wdev,
1825 const void *data,
1826 int data_len)
1827{
1828 int ret;
1829
1830 vos_ssr_protect(__func__);
1831 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1832 vos_ssr_unprotect(__func__);
1833
1834 return ret;
1835}
1836
1837/*
1838 * undef short names defined for get station command
1839 * used by __wlan_hdd_cfg80211_get_station_cmd()
1840 */
1841#undef STATION_INVALID
1842#undef STATION_INFO
1843#undef STATION_ASSOC_FAIL_REASON
1844#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301845
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1847
1848static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1849 struct sk_buff *vendor_event)
1850{
1851 if (nla_put_u8(vendor_event,
1852 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1853 stats->rate.preamble) ||
1854 nla_put_u8(vendor_event,
1855 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1856 stats->rate.nss) ||
1857 nla_put_u8(vendor_event,
1858 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1859 stats->rate.bw) ||
1860 nla_put_u8(vendor_event,
1861 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1862 stats->rate.rateMcsIdx) ||
1863 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1864 stats->rate.bitrate ) ||
1865 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1866 stats->txMpdu ) ||
1867 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1868 stats->rxMpdu ) ||
1869 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1870 stats->mpduLost ) ||
1871 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1872 stats->retries) ||
1873 nla_put_u32(vendor_event,
1874 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1875 stats->retriesShort ) ||
1876 nla_put_u32(vendor_event,
1877 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1878 stats->retriesLong))
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR,
1881 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1882 return FALSE;
1883 }
1884 return TRUE;
1885}
1886
1887static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1888 struct sk_buff *vendor_event)
1889{
1890 u32 i = 0;
1891 struct nlattr *rateInfo;
1892 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1893 stats->type) ||
1894 nla_put(vendor_event,
1895 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1896 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1897 nla_put_u32(vendor_event,
1898 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1899 stats->capabilities) ||
1900 nla_put_u32(vendor_event,
1901 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1902 stats->numRate))
1903 {
1904 hddLog(VOS_TRACE_LEVEL_ERROR,
1905 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1906 goto error;
1907 }
1908
1909 rateInfo = nla_nest_start(vendor_event,
1910 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301911 if(!rateInfo)
1912 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301913 for (i = 0; i < stats->numRate; i++)
1914 {
1915 struct nlattr *rates;
1916 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1917 stats->rateStats +
1918 (i * sizeof(tSirWifiRateStat)));
1919 rates = nla_nest_start(vendor_event, i);
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05301920
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301921 if(!rates)
1922 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1925 {
1926 hddLog(VOS_TRACE_LEVEL_ERROR,
1927 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1928 return FALSE;
1929 }
1930 nla_nest_end(vendor_event, rates);
1931 }
1932 nla_nest_end(vendor_event, rateInfo);
1933
1934 return TRUE;
1935error:
1936 return FALSE;
1937}
1938
1939static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1940 struct sk_buff *vendor_event)
1941{
1942 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1943 stats->ac ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1946 stats->txMpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1949 stats->rxMpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1952 stats->txMcast ) ||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1955 stats->rxMcast ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1958 stats->rxAmpdu ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1961 stats->txAmpdu ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1964 stats->mpduLost )||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1967 stats->retries ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1970 stats->retriesShort ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1973 stats->retriesLong ) ||
1974 nla_put_u32(vendor_event,
1975 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1976 stats->contentionTimeMin ) ||
1977 nla_put_u32(vendor_event,
1978 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1979 stats->contentionTimeMax ) ||
1980 nla_put_u32(vendor_event,
1981 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1982 stats->contentionTimeAvg ) ||
1983 nla_put_u32(vendor_event,
1984 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1985 stats->contentionNumSamples ))
1986 {
1987 hddLog(VOS_TRACE_LEVEL_ERROR,
1988 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1989 return FALSE;
1990 }
1991 return TRUE;
1992}
1993
1994static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1995 struct sk_buff *vendor_event)
1996{
Dino Myclec8f3f332014-07-21 16:48:27 +05301997 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301998 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
2001 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2002 nla_put_u32(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2004 stats->state ) ||
2005 nla_put_u32(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2007 stats->roaming ) ||
2008 nla_put_u32(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2010 stats->capabilities ) ||
2011 nla_put(vendor_event,
2012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2013 strlen(stats->ssid), stats->ssid) ||
2014 nla_put(vendor_event,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2016 WNI_CFG_BSSID_LEN, stats->bssid) ||
2017 nla_put(vendor_event,
2018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2019 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2020 nla_put(vendor_event,
2021 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2022 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2023 )
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2027 return FALSE;
2028 }
2029 return TRUE;
2030}
2031
Dino Mycle3b9536d2014-07-09 22:05:24 +05302032static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2033 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302034 struct sk_buff *vendor_event)
2035{
2036 int i = 0;
2037 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302038 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2039 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302040 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302041
Sunil Duttc69bccb2014-05-26 21:30:20 +05302042 if (FALSE == put_wifi_interface_info(
2043 &pWifiIfaceStat->info,
2044 vendor_event))
2045 {
2046 hddLog(VOS_TRACE_LEVEL_ERROR,
2047 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2048 return FALSE;
2049
2050 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302051 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2052 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2053 if (NULL == pWifiIfaceStatTL)
2054 {
2055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2056 return FALSE;
2057 }
2058
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302059 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2060 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2061 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2062 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2063
2064 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2065 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302068
2069 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2070 {
2071 if (VOS_STATUS_SUCCESS ==
2072 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2073 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2074 {
2075 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2076 * obtained from TL structure
2077 */
2078
2079 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2080 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302081 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2082
Srinivas Dasari98947432014-11-07 19:41:24 +05302083 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2084 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2085 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2086 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2087 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2088 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2089 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302091
Srinivas Dasari98947432014-11-07 19:41:24 +05302092 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2093 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2094 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2095 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2096 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2097 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2098 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2099 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302100
Srinivas Dasari98947432014-11-07 19:41:24 +05302101 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2102 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2104 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2106 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2108 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302109 }
2110 else
2111 {
2112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2113 }
2114
Dino Mycle3b9536d2014-07-09 22:05:24 +05302115 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2116 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2117 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2118 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2119 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2120 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2121 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2122 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2123 }
2124 else
2125 {
2126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2127 }
2128
2129
Sunil Duttc69bccb2014-05-26 21:30:20 +05302130
2131 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2133 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2134 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2136 pWifiIfaceStat->beaconRx) ||
2137 nla_put_u32(vendor_event,
2138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2139 pWifiIfaceStat->mgmtRx) ||
2140 nla_put_u32(vendor_event,
2141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2142 pWifiIfaceStat->mgmtActionRx) ||
2143 nla_put_u32(vendor_event,
2144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2145 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302146 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2148 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302149 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2151 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302152 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2154 pWifiIfaceStat->rssiAck))
2155 {
2156 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302157 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2158 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302159 return FALSE;
2160 }
2161
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302162#ifdef FEATURE_EXT_LL_STAT
2163 /*
2164 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2165 * then host should send Leaky AP stats to upper layer,
2166 * otherwise no need to send these stats.
2167 */
2168 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2169 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2170 )
2171 {
2172 hddLog(VOS_TRACE_LEVEL_INFO,
2173 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2174 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2175 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2176 pWifiIfaceStat->leakyApStat.rx_leak_window,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2178 if (nla_put_u32(vendor_event,
2179 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2180 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2181 nla_put_u32(vendor_event,
2182 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2183 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2184 nla_put_u32(vendor_event,
2185 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2186 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302187 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302188 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2189 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2190 {
2191 hddLog(VOS_TRACE_LEVEL_ERROR,
2192 FL("EXT_LL_STAT put fail"));
2193 vos_mem_free(pWifiIfaceStatTL);
2194 return FALSE;
2195 }
2196 }
2197#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302198 wmmInfo = nla_nest_start(vendor_event,
2199 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302200 if(!wmmInfo)
2201 {
2202 vos_mem_free(pWifiIfaceStatTL);
2203 return FALSE;
2204 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302205 for (i = 0; i < WIFI_AC_MAX; i++)
2206 {
2207 struct nlattr *wmmStats;
2208 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302209 if(!wmmStats)
2210 {
2211 vos_mem_free(pWifiIfaceStatTL);
2212 return FALSE;
2213 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 if (FALSE == put_wifi_wmm_ac_stat(
2215 &pWifiIfaceStat->AccessclassStats[i],
2216 vendor_event))
2217 {
2218 hddLog(VOS_TRACE_LEVEL_ERROR,
2219 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302220 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 return FALSE;
2222 }
2223
2224 nla_nest_end(vendor_event, wmmStats);
2225 }
2226 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302227 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302228 return TRUE;
2229}
2230
2231static tSirWifiInterfaceMode
2232 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2233{
2234 switch (deviceMode)
2235 {
2236 case WLAN_HDD_INFRA_STATION:
2237 return WIFI_INTERFACE_STA;
2238 case WLAN_HDD_SOFTAP:
2239 return WIFI_INTERFACE_SOFTAP;
2240 case WLAN_HDD_P2P_CLIENT:
2241 return WIFI_INTERFACE_P2P_CLIENT;
2242 case WLAN_HDD_P2P_GO:
2243 return WIFI_INTERFACE_P2P_GO;
2244 case WLAN_HDD_IBSS:
2245 return WIFI_INTERFACE_IBSS;
2246 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302247 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302248 }
2249}
2250
2251static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2252 tpSirWifiInterfaceInfo pInfo)
2253{
2254 v_U8_t *staMac = NULL;
2255 hdd_station_ctx_t *pHddStaCtx;
2256 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2257 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2258
2259 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2260
2261 vos_mem_copy(pInfo->macAddr,
2262 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2263
2264 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2265 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2266 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2267 {
2268 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2269 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2270 {
2271 pInfo->state = WIFI_DISCONNECTED;
2272 }
2273 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2274 {
2275 hddLog(VOS_TRACE_LEVEL_ERROR,
2276 "%s: Session ID %d, Connection is in progress", __func__,
2277 pAdapter->sessionId);
2278 pInfo->state = WIFI_ASSOCIATING;
2279 }
2280 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2281 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2282 {
2283 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2284 hddLog(VOS_TRACE_LEVEL_ERROR,
2285 "%s: client " MAC_ADDRESS_STR
2286 " is in the middle of WPS/EAPOL exchange.", __func__,
2287 MAC_ADDR_ARRAY(staMac));
2288 pInfo->state = WIFI_AUTHENTICATING;
2289 }
2290 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2291 {
2292 pInfo->state = WIFI_ASSOCIATED;
2293 vos_mem_copy(pInfo->bssid,
2294 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2295 vos_mem_copy(pInfo->ssid,
2296 pHddStaCtx->conn_info.SSID.SSID.ssId,
2297 pHddStaCtx->conn_info.SSID.SSID.length);
2298 //NULL Terminate the string.
2299 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2300 }
2301 }
2302 vos_mem_copy(pInfo->countryStr,
2303 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2304
2305 vos_mem_copy(pInfo->apCountryStr,
2306 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2307
2308 return TRUE;
2309}
2310
2311/*
2312 * hdd_link_layer_process_peer_stats () - This function is called after
2313 * receiving Link Layer Peer statistics from FW.This function converts
2314 * the firmware data to the NL data and sends the same to the kernel/upper
2315 * layers.
2316 */
2317static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2318 v_VOID_t *pData)
2319{
2320 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 tpSirWifiPeerStat pWifiPeerStat;
2322 tpSirWifiPeerInfo pWifiPeerInfo;
2323 struct nlattr *peerInfo;
2324 struct sk_buff *vendor_event;
2325 int status, i;
2326
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302327 ENTER();
2328
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 status = wlan_hdd_validate_context(pHddCtx);
2330 if (0 != status)
2331 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302332 return;
2333 }
2334
2335 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2336
2337 hddLog(VOS_TRACE_LEVEL_INFO,
2338 "LL_STATS_PEER_ALL : numPeers %u",
2339 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302340 /*
2341 * Allocate a size of 4096 for the peer stats comprising
2342 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2343 * sizeof (tSirWifiRateStat).Each field is put with an
2344 * NL attribute.The size of 4096 is considered assuming
2345 * that number of rates shall not exceed beyond 50 with
2346 * the sizeof (tSirWifiRateStat) being 32.
2347 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302348 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2349 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302350 if (!vendor_event)
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302353 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354 __func__);
2355 return;
2356 }
2357 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302358 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2360 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302361 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2362 pWifiPeerStat->numPeers))
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR,
2365 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2366 kfree_skb(vendor_event);
2367 return;
2368 }
2369
2370 peerInfo = nla_nest_start(vendor_event,
2371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302372 if(!peerInfo)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR,
2375 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2376 __func__);
2377 kfree_skb(vendor_event);
2378 return;
2379 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302380
2381 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2382 pWifiPeerStat->peerInfo);
2383
2384 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2385 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302386 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302387 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302388
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302389 if(!peers)
2390 {
2391 hddLog(VOS_TRACE_LEVEL_ERROR,
2392 "%s: peer stats put fail",
2393 __func__);
2394 kfree_skb(vendor_event);
2395 return;
2396 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302397 if (FALSE == put_wifi_peer_info(
2398 pWifiPeerInfo, vendor_event))
2399 {
2400 hddLog(VOS_TRACE_LEVEL_ERROR,
2401 "%s: put_wifi_peer_info put fail", __func__);
2402 kfree_skb(vendor_event);
2403 return;
2404 }
2405
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05302406 pWifiPeerInfo = (tpSirWifiPeerInfo)((uint8 *)pWifiPeerInfo +
2407 (sizeof(tSirWifiPeerInfo) - sizeof(tSirWifiRateStat)) +
2408 (numRate * sizeof(tSirWifiRateStat)));
2409
Sunil Duttc69bccb2014-05-26 21:30:20 +05302410 nla_nest_end(vendor_event, peers);
2411 }
2412 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302413 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302415}
2416
2417/*
2418 * hdd_link_layer_process_iface_stats () - This function is called after
2419 * receiving Link Layer Interface statistics from FW.This function converts
2420 * the firmware data to the NL data and sends the same to the kernel/upper
2421 * layers.
2422 */
2423static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2424 v_VOID_t *pData)
2425{
2426 tpSirWifiIfaceStat pWifiIfaceStat;
2427 struct sk_buff *vendor_event;
2428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2429 int status;
2430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302431 ENTER();
2432
Sunil Duttc69bccb2014-05-26 21:30:20 +05302433 status = wlan_hdd_validate_context(pHddCtx);
2434 if (0 != status)
2435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302436 return;
2437 }
2438 /*
2439 * Allocate a size of 4096 for the interface stats comprising
2440 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2441 * assuming that all these fit with in the limit.Please take
2442 * a call on the limit based on the data requirements on
2443 * interface statistics.
2444 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302447 if (!vendor_event)
2448 {
2449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302451 return;
2452 }
2453
2454 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2455
Dino Mycle3b9536d2014-07-09 22:05:24 +05302456
2457 if (FALSE == hdd_get_interface_info( pAdapter,
2458 &pWifiIfaceStat->info))
2459 {
2460 hddLog(VOS_TRACE_LEVEL_ERROR,
2461 FL("hdd_get_interface_info get fail") );
2462 kfree_skb(vendor_event);
2463 return;
2464 }
2465
2466 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2467 vendor_event))
2468 {
2469 hddLog(VOS_TRACE_LEVEL_ERROR,
2470 FL("put_wifi_iface_stats fail") );
2471 kfree_skb(vendor_event);
2472 return;
2473 }
2474
Sunil Duttc69bccb2014-05-26 21:30:20 +05302475 hddLog(VOS_TRACE_LEVEL_INFO,
2476 "WMI_LINK_STATS_IFACE Data");
2477
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302478 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302479
2480 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481}
2482
2483/*
2484 * hdd_link_layer_process_radio_stats () - This function is called after
2485 * receiving Link Layer Radio statistics from FW.This function converts
2486 * the firmware data to the NL data and sends the same to the kernel/upper
2487 * layers.
2488 */
2489static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2490 v_VOID_t *pData)
2491{
2492 int status, i;
2493 tpSirWifiRadioStat pWifiRadioStat;
2494 tpSirWifiChannelStats pWifiChannelStats;
2495 struct sk_buff *vendor_event;
2496 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2497 struct nlattr *chList;
2498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302499 ENTER();
2500
Sunil Duttc69bccb2014-05-26 21:30:20 +05302501 status = wlan_hdd_validate_context(pHddCtx);
2502 if (0 != status)
2503 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302504 return;
2505 }
2506 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2507
2508 hddLog(VOS_TRACE_LEVEL_INFO,
2509 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302510 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302511 " radio is %d onTime is %u "
2512 " txTime is %u rxTime is %u "
2513 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302514 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515 " onTimePnoScan is %u onTimeHs20 is %u "
2516 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302517 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302518 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2519 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2520 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302521 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302522 pWifiRadioStat->onTimeRoamScan,
2523 pWifiRadioStat->onTimePnoScan,
2524 pWifiRadioStat->onTimeHs20,
2525 pWifiRadioStat->numChannels);
2526 /*
2527 * Allocate a size of 4096 for the Radio stats comprising
2528 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2529 * (tSirWifiChannelStats).Each channel data is put with an
2530 * NL attribute.The size of 4096 is considered assuming that
2531 * number of channels shall not exceed beyond 60 with the
2532 * sizeof (tSirWifiChannelStats) being 24 bytes.
2533 */
2534
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302535 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2536 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302537 if (!vendor_event)
2538 {
2539 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302540 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 return;
2542 }
2543
2544 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302545 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2546 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2547 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2549 pWifiRadioStat->radio) ||
2550 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302551 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2552 NUM_RADIOS) ||
2553 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2555 pWifiRadioStat->onTime) ||
2556 nla_put_u32(vendor_event,
2557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2558 pWifiRadioStat->txTime) ||
2559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2561 pWifiRadioStat->rxTime) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2564 pWifiRadioStat->onTimeScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2567 pWifiRadioStat->onTimeNbd) ||
2568 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2570 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302571 nla_put_u32(vendor_event,
2572 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2573 pWifiRadioStat->onTimeRoamScan) ||
2574 nla_put_u32(vendor_event,
2575 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2576 pWifiRadioStat->onTimePnoScan) ||
2577 nla_put_u32(vendor_event,
2578 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2579 pWifiRadioStat->onTimeHs20) ||
2580 nla_put_u32(vendor_event,
2581 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2582 pWifiRadioStat->numChannels))
2583 {
2584 hddLog(VOS_TRACE_LEVEL_ERROR,
2585 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2586 kfree_skb(vendor_event);
2587 return ;
2588 }
2589
2590 chList = nla_nest_start(vendor_event,
2591 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302592 if(!chList)
2593 {
2594 hddLog(VOS_TRACE_LEVEL_ERROR,
2595 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2596 __func__);
2597 kfree_skb(vendor_event);
2598 return;
2599 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302600 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2601 {
2602 struct nlattr *chInfo;
2603
2604 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2605 pWifiRadioStat->channels +
2606 (i * sizeof(tSirWifiChannelStats)));
2607
Sunil Duttc69bccb2014-05-26 21:30:20 +05302608 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302609 if(!chInfo)
2610 {
2611 hddLog(VOS_TRACE_LEVEL_ERROR,
2612 "%s: failed to put chInfo",
2613 __func__);
2614 kfree_skb(vendor_event);
2615 return;
2616 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302617
2618 if (nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2620 pWifiChannelStats->channel.width) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2623 pWifiChannelStats->channel.centerFreq) ||
2624 nla_put_u32(vendor_event,
2625 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2626 pWifiChannelStats->channel.centerFreq0) ||
2627 nla_put_u32(vendor_event,
2628 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2629 pWifiChannelStats->channel.centerFreq1) ||
2630 nla_put_u32(vendor_event,
2631 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2632 pWifiChannelStats->onTime) ||
2633 nla_put_u32(vendor_event,
2634 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2635 pWifiChannelStats->ccaBusyTime))
2636 {
2637 hddLog(VOS_TRACE_LEVEL_ERROR,
2638 FL("cfg80211_vendor_event_alloc failed") );
2639 kfree_skb(vendor_event);
2640 return ;
2641 }
2642 nla_nest_end(vendor_event, chInfo);
2643 }
2644 nla_nest_end(vendor_event, chList);
2645
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302646 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302647
2648 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302649 return;
2650}
2651
2652/*
2653 * hdd_link_layer_stats_ind_callback () - This function is called after
2654 * receiving Link Layer indications from FW.This callback converts the firmware
2655 * data to the NL data and send the same to the kernel/upper layers.
2656 */
2657static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2658 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302659 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660{
Dino Mycled3d50022014-07-07 12:58:25 +05302661 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2662 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302663 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302664 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665 int status;
2666
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302667 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302668
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302669 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302670 if (0 != status)
2671 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 return;
2673 }
2674
Dino Mycled3d50022014-07-07 12:58:25 +05302675 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2676 if (NULL == pAdapter)
2677 {
2678 hddLog(VOS_TRACE_LEVEL_ERROR,
2679 FL(" MAC address %pM does not exist with host"),
2680 macAddr);
2681 return;
2682 }
2683
Sunil Duttc69bccb2014-05-26 21:30:20 +05302684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302685 "%s: Interface: %s LLStats indType: %d", __func__,
2686 pAdapter->dev->name, indType);
2687
Sunil Duttc69bccb2014-05-26 21:30:20 +05302688 switch (indType)
2689 {
2690 case SIR_HAL_LL_STATS_RESULTS_RSP:
2691 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302692 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302693 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2694 "respId = %u, moreResultToFollow = %u",
2695 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2696 macAddr, linkLayerStatsResults->respId,
2697 linkLayerStatsResults->moreResultToFollow);
2698
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302699 spin_lock(&hdd_context_lock);
2700 context = &pHddCtx->ll_stats_context;
2701 /* validate response received from target */
2702 if ((context->request_id != linkLayerStatsResults->respId) ||
2703 !(context->request_bitmap & linkLayerStatsResults->paramId))
2704 {
2705 spin_unlock(&hdd_context_lock);
2706 hddLog(LOGE,
2707 FL("Error : Request id %d response id %d request bitmap 0x%x"
2708 "response bitmap 0x%x"),
2709 context->request_id, linkLayerStatsResults->respId,
2710 context->request_bitmap, linkLayerStatsResults->paramId);
2711 return;
2712 }
2713 spin_unlock(&hdd_context_lock);
2714
Sunil Duttc69bccb2014-05-26 21:30:20 +05302715 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2716 {
2717 hdd_link_layer_process_radio_stats(pAdapter,
2718 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302719 spin_lock(&hdd_context_lock);
2720 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2721 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302722 }
2723 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2724 {
2725 hdd_link_layer_process_iface_stats(pAdapter,
2726 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302727 spin_lock(&hdd_context_lock);
2728 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2729 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302730 }
2731 else if ( linkLayerStatsResults->paramId &
2732 WMI_LINK_STATS_ALL_PEER )
2733 {
2734 hdd_link_layer_process_peer_stats(pAdapter,
2735 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302736 spin_lock(&hdd_context_lock);
2737 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2738 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302739 } /* WMI_LINK_STATS_ALL_PEER */
2740 else
2741 {
2742 hddLog(VOS_TRACE_LEVEL_ERROR,
2743 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2744 }
2745
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302746 spin_lock(&hdd_context_lock);
2747 /* complete response event if all requests are completed */
2748 if (0 == context->request_bitmap)
2749 complete(&context->response_event);
2750 spin_unlock(&hdd_context_lock);
2751
Sunil Duttc69bccb2014-05-26 21:30:20 +05302752 break;
2753 }
2754 default:
2755 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2756 break;
2757 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302758
2759 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302760 return;
2761}
2762
2763const struct
2764nla_policy
2765qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2766{
2767 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2768 { .type = NLA_U32 },
2769 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2770 { .type = NLA_U32 },
2771};
2772
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302773static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2774 struct wireless_dev *wdev,
2775 const void *data,
2776 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302777{
2778 int status;
2779 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302780 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302781 struct net_device *dev = wdev->netdev;
2782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302785 ENTER();
2786
Sunil Duttc69bccb2014-05-26 21:30:20 +05302787 status = wlan_hdd_validate_context(pHddCtx);
2788 if (0 != status)
2789 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302790 return -EINVAL;
2791 }
2792
2793 if (NULL == pAdapter)
2794 {
2795 hddLog(VOS_TRACE_LEVEL_ERROR,
2796 FL("HDD adapter is Null"));
2797 return -ENODEV;
2798 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302799 /* check the LLStats Capability */
2800 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2801 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2802 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302803 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302804 FL("Link Layer Statistics not supported by Firmware"));
2805 return -EINVAL;
2806 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302807
2808 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2809 (struct nlattr *)data,
2810 data_len, qca_wlan_vendor_ll_set_policy))
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2813 return -EINVAL;
2814 }
2815 if (!tb_vendor
2816 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2817 {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2819 return -EINVAL;
2820 }
2821 if (!tb_vendor[
2822 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2823 {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2825 return -EINVAL;
2826 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302827 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302828 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302829
Dino Mycledf0a5d92014-07-04 09:41:55 +05302830 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302831 nla_get_u32(
2832 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2833
Dino Mycledf0a5d92014-07-04 09:41:55 +05302834 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302835 nla_get_u32(
2836 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2837
Dino Mycled3d50022014-07-07 12:58:25 +05302838 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2839 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840
2841
2842 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302843 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2844 "Statistics Gathering = %d ",
2845 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2846 linkLayerStatsSetReq.mpduSizeThreshold,
2847 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302848
2849 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2850 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302851 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 {
2853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2854 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302855 return -EINVAL;
2856
2857 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302858
Sunil Duttc69bccb2014-05-26 21:30:20 +05302859 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302860 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302861 {
2862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2863 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302864 return -EINVAL;
2865 }
2866
2867 pAdapter->isLinkLayerStatsSet = 1;
2868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302869 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302870 return 0;
2871}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302872static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2873 struct wireless_dev *wdev,
2874 const void *data,
2875 int data_len)
2876{
2877 int ret = 0;
2878
2879 vos_ssr_protect(__func__);
2880 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2881 vos_ssr_unprotect(__func__);
2882
2883 return ret;
2884}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302885
2886const struct
2887nla_policy
2888qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2889{
2890 /* Unsigned 32bit value provided by the caller issuing the GET stats
2891 * command. When reporting
2892 * the stats results, the driver uses the same value to indicate
2893 * which GET request the results
2894 * correspond to.
2895 */
2896 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2897
2898 /* Unsigned 32bit value . bit mask to identify what statistics are
2899 requested for retrieval */
2900 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2901};
2902
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302903static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2904 struct wireless_dev *wdev,
2905 const void *data,
2906 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302907{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302908 unsigned long rc;
2909 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302910 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2911 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302912 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302913 struct net_device *dev = wdev->netdev;
2914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302915 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302916 int status;
2917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302918 ENTER();
2919
Sunil Duttc69bccb2014-05-26 21:30:20 +05302920 status = wlan_hdd_validate_context(pHddCtx);
2921 if (0 != status)
2922 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302923 return -EINVAL ;
2924 }
2925
2926 if (NULL == pAdapter)
2927 {
2928 hddLog(VOS_TRACE_LEVEL_FATAL,
2929 "%s: HDD adapter is Null", __func__);
2930 return -ENODEV;
2931 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302932
2933 if (pHddStaCtx == NULL)
2934 {
2935 hddLog(VOS_TRACE_LEVEL_FATAL,
2936 "%s: HddStaCtx is Null", __func__);
2937 return -ENODEV;
2938 }
2939
Dino Mycledf0a5d92014-07-04 09:41:55 +05302940 /* check the LLStats Capability */
2941 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2942 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2943 {
2944 hddLog(VOS_TRACE_LEVEL_ERROR,
2945 FL("Link Layer Statistics not supported by Firmware"));
2946 return -EINVAL;
2947 }
2948
Sunil Duttc69bccb2014-05-26 21:30:20 +05302949
2950 if (!pAdapter->isLinkLayerStatsSet)
2951 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302952 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 "%s: isLinkLayerStatsSet : %d",
2954 __func__, pAdapter->isLinkLayerStatsSet);
2955 return -EINVAL;
2956 }
2957
Mukul Sharma10313ba2015-07-29 19:14:39 +05302958 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2959 {
2960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2961 "%s: Roaming in progress, so unable to proceed this request", __func__);
2962 return -EBUSY;
2963 }
2964
Sunil Duttc69bccb2014-05-26 21:30:20 +05302965 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2966 (struct nlattr *)data,
2967 data_len, qca_wlan_vendor_ll_get_policy))
2968 {
2969 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2970 return -EINVAL;
2971 }
2972
2973 if (!tb_vendor
2974 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2977 return -EINVAL;
2978 }
2979
2980 if (!tb_vendor
2981 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2982 {
2983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2984 return -EINVAL;
2985 }
2986
Sunil Duttc69bccb2014-05-26 21:30:20 +05302987
Dino Mycledf0a5d92014-07-04 09:41:55 +05302988 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302989 nla_get_u32( tb_vendor[
2990 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302991 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302992 nla_get_u32( tb_vendor[
2993 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2994
Dino Mycled3d50022014-07-07 12:58:25 +05302995 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2996 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302997
2998 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302999 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
3000 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303001 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303002
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303003 spin_lock(&hdd_context_lock);
3004 context = &pHddCtx->ll_stats_context;
3005 context->request_id = linkLayerStatsGetReq.reqId;
3006 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3007 INIT_COMPLETION(context->response_event);
3008 spin_unlock(&hdd_context_lock);
3009
Sunil Duttc69bccb2014-05-26 21:30:20 +05303010 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303011 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 {
3013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3014 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303015 return -EINVAL;
3016 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303017
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303018 rc = wait_for_completion_timeout(&context->response_event,
3019 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3020 if (!rc)
3021 {
3022 hddLog(LOGE,
3023 FL("Target response timed out request id %d request bitmap 0x%x"),
3024 context->request_id, context->request_bitmap);
3025 return -ETIMEDOUT;
3026 }
3027
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303028 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303029 return 0;
3030}
3031
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303032static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3033 struct wireless_dev *wdev,
3034 const void *data,
3035 int data_len)
3036{
3037 int ret = 0;
3038
3039 vos_ssr_protect(__func__);
3040 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3041 vos_ssr_unprotect(__func__);
3042
3043 return ret;
3044}
3045
Sunil Duttc69bccb2014-05-26 21:30:20 +05303046const struct
3047nla_policy
3048qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3049{
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3051 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3052 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3053 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3054};
3055
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303056static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3057 struct wireless_dev *wdev,
3058 const void *data,
3059 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060{
3061 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3062 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303063 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303064 struct net_device *dev = wdev->netdev;
3065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3066 u32 statsClearReqMask;
3067 u8 stopReq;
3068 int status;
3069
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303070 ENTER();
3071
Sunil Duttc69bccb2014-05-26 21:30:20 +05303072 status = wlan_hdd_validate_context(pHddCtx);
3073 if (0 != status)
3074 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303075 return -EINVAL;
3076 }
3077
3078 if (NULL == pAdapter)
3079 {
3080 hddLog(VOS_TRACE_LEVEL_FATAL,
3081 "%s: HDD adapter is Null", __func__);
3082 return -ENODEV;
3083 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303084 /* check the LLStats Capability */
3085 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3086 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3087 {
3088 hddLog(VOS_TRACE_LEVEL_ERROR,
3089 FL("Enable LLStats Capability"));
3090 return -EINVAL;
3091 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303092
3093 if (!pAdapter->isLinkLayerStatsSet)
3094 {
3095 hddLog(VOS_TRACE_LEVEL_FATAL,
3096 "%s: isLinkLayerStatsSet : %d",
3097 __func__, pAdapter->isLinkLayerStatsSet);
3098 return -EINVAL;
3099 }
3100
3101 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3102 (struct nlattr *)data,
3103 data_len, qca_wlan_vendor_ll_clr_policy))
3104 {
3105 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3106 return -EINVAL;
3107 }
3108
3109 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3110
3111 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3112 {
3113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3114 return -EINVAL;
3115
3116 }
3117
Sunil Duttc69bccb2014-05-26 21:30:20 +05303118
Dino Mycledf0a5d92014-07-04 09:41:55 +05303119 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120 nla_get_u32(
3121 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3122
Dino Mycledf0a5d92014-07-04 09:41:55 +05303123 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303124 nla_get_u8(
3125 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3126
3127 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303128 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303129
Dino Mycled3d50022014-07-07 12:58:25 +05303130 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3131 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303132
3133 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303134 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3135 "statsClearReqMask = 0x%X, stopReq = %d",
3136 linkLayerStatsClearReq.reqId,
3137 linkLayerStatsClearReq.macAddr,
3138 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303139 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303140
3141 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303142 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303143 {
3144 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303145 hdd_station_ctx_t *pHddStaCtx;
3146
3147 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3148 if (VOS_STATUS_SUCCESS !=
3149 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3150 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3151 {
3152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3153 "WLANTL_ClearInterfaceStats Failed", __func__);
3154 return -EINVAL;
3155 }
3156 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3157 (statsClearReqMask & WIFI_STATS_IFACE)) {
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3159 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3160 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3161 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3162 }
3163
Sunil Duttc69bccb2014-05-26 21:30:20 +05303164 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3165 2 * sizeof(u32) +
3166 NLMSG_HDRLEN);
3167
3168 if (temp_skbuff != NULL)
3169 {
3170
3171 if (nla_put_u32(temp_skbuff,
3172 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3173 statsClearReqMask) ||
3174 nla_put_u32(temp_skbuff,
3175 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3176 stopReq))
3177 {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3179 kfree_skb(temp_skbuff);
3180 return -EINVAL;
3181 }
3182 /* If the ask is to stop the stats collection as part of clear
3183 * (stopReq = 1) , ensure that no further requests of get
3184 * go to the firmware by having isLinkLayerStatsSet set to 0.
3185 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303186 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303187 * case the firmware is just asked to clear the statistics.
3188 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303189 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303190 pAdapter->isLinkLayerStatsSet = 0;
3191 return cfg80211_vendor_cmd_reply(temp_skbuff);
3192 }
3193 return -ENOMEM;
3194 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303195
3196 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303197 return -EINVAL;
3198}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303199static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3200 struct wireless_dev *wdev,
3201 const void *data,
3202 int data_len)
3203{
3204 int ret = 0;
3205
3206 vos_ssr_protect(__func__);
3207 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3208 vos_ssr_unprotect(__func__);
3209
3210 return ret;
3211
3212
3213}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303214#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3215
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216#ifdef WLAN_FEATURE_EXTSCAN
3217static const struct nla_policy
3218wlan_hdd_extscan_config_policy
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3220{
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3222 { .type = NLA_U32 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3224 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3226 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3232
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3237 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3239 { .type = NLA_U32 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3241 { .type = NLA_U32 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3243 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3245 { .type = NLA_U32 },
3246 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3247 { .type = NLA_U32 },
3248 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3249 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303250 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3251 { .type = NLA_U8 },
3252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303253 { .type = NLA_U8 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3255 { .type = NLA_U8 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3257 { .type = NLA_U8 },
3258
3259 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3260 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3262 .type = NLA_UNSPEC,
3263 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3265 { .type = NLA_S32 },
3266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3267 { .type = NLA_S32 },
3268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3269 { .type = NLA_U32 },
3270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3271 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303272 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3273 { .type = NLA_U32 },
3274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3275 { .type = NLA_BINARY,
3276 .len = IEEE80211_MAX_SSID_LEN + 1 },
3277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3280 { .type = NLA_U32 },
3281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3282 { .type = NLA_U8 },
3283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3284 { .type = NLA_S32 },
3285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3286 { .type = NLA_S32 },
3287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3288 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303289};
3290
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291/**
3292 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3293 * @ctx: hdd global context
3294 * @data: capabilities data
3295 *
3296 * Return: none
3297 */
3298static void
3299wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303301 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303303 tSirEXTScanCapabilitiesEvent *data =
3304 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303306 ENTER();
3307
3308 if (wlan_hdd_validate_context(pHddCtx))
3309 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303310 return;
3311 }
3312
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303313 if (!pMsg)
3314 {
3315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3316 return;
3317 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303318
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 vos_spin_lock_acquire(&hdd_context_lock);
3320
3321 context = &pHddCtx->ext_scan_context;
3322 /* validate response received from target*/
3323 if (context->request_id != data->requestId)
3324 {
3325 vos_spin_lock_release(&hdd_context_lock);
3326 hddLog(LOGE,
3327 FL("Target response id did not match: request_id %d resposne_id %d"),
3328 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303329 return;
3330 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303331 else
3332 {
3333 context->capability_response = *data;
3334 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 }
3336
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303337 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338
Dino Mycle6fb96c12014-06-10 11:52:40 +05303339 return;
3340}
3341
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303342/*
3343 * define short names for the global vendor params
3344 * used by wlan_hdd_send_ext_scan_capability()
3345 */
3346#define PARAM_REQUEST_ID \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3348#define PARAM_STATUS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3350#define MAX_SCAN_CACHE_SIZE \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3352#define MAX_SCAN_BUCKETS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3354#define MAX_AP_CACHE_PER_SCAN \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3356#define MAX_RSSI_SAMPLE_SIZE \
3357 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3358#define MAX_SCAN_RPT_THRHOLD \
3359 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3360#define MAX_HOTLIST_BSSIDS \
3361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3362#define MAX_BSSID_HISTORY_ENTRIES \
3363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3364#define MAX_HOTLIST_SSIDS \
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303366#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303368
3369static int wlan_hdd_send_ext_scan_capability(void *ctx)
3370{
3371 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3372 struct sk_buff *skb = NULL;
3373 int ret;
3374 tSirEXTScanCapabilitiesEvent *data;
3375 tANI_U32 nl_buf_len;
3376
3377 ret = wlan_hdd_validate_context(pHddCtx);
3378 if (0 != ret)
3379 {
3380 return ret;
3381 }
3382
3383 data = &(pHddCtx->ext_scan_context.capability_response);
3384
3385 nl_buf_len = NLMSG_HDRLEN;
3386 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3387 (sizeof(data->status) + NLA_HDRLEN) +
3388 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3389 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3390 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3391 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3392 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3393 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3394 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3395 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3396
3397 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3398
3399 if (!skb)
3400 {
3401 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3402 return -ENOMEM;
3403 }
3404
3405 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3406 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3407 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3408 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3409 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3410 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3411 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3412 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3413
3414 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3415 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3416 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3417 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3418 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3419 data->maxApPerScan) ||
3420 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3421 data->maxRssiSampleSize) ||
3422 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3423 data->maxScanReportingThreshold) ||
3424 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3425 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3426 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303427 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3428 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303429 {
3430 hddLog(LOGE, FL("nla put fail"));
3431 goto nla_put_failure;
3432 }
3433
3434 cfg80211_vendor_cmd_reply(skb);
3435 return 0;
3436
3437nla_put_failure:
3438 kfree_skb(skb);
3439 return -EINVAL;;
3440}
3441
3442/*
3443 * done with short names for the global vendor params
3444 * used by wlan_hdd_send_ext_scan_capability()
3445 */
3446#undef PARAM_REQUEST_ID
3447#undef PARAM_STATUS
3448#undef MAX_SCAN_CACHE_SIZE
3449#undef MAX_SCAN_BUCKETS
3450#undef MAX_AP_CACHE_PER_SCAN
3451#undef MAX_RSSI_SAMPLE_SIZE
3452#undef MAX_SCAN_RPT_THRHOLD
3453#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303454#undef MAX_BSSID_HISTORY_ENTRIES
3455#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303456
3457static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3458{
3459 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3460 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303462 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303464 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303467 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303469 if (!pMsg)
3470 {
3471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 return;
3473 }
3474
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3476 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3477
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303478 context = &pHddCtx->ext_scan_context;
3479 spin_lock(&hdd_context_lock);
3480 if (context->request_id == pData->requestId) {
3481 context->response_status = pData->status ? -EINVAL : 0;
3482 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303484 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485
3486 /*
3487 * Store the Request ID for comparing with the requestID obtained
3488 * in other requests.HDD shall return a failure is the extscan_stop
3489 * request is issued with a different requestId as that of the
3490 * extscan_start request. Also, This requestId shall be used while
3491 * indicating the full scan results to the upper layers.
3492 * The requestId is stored with the assumption that the firmware
3493 * shall return the ext scan start request's requestId in ext scan
3494 * start response.
3495 */
3496 if (pData->status == 0)
3497 pMac->sme.extScanStartReqId = pData->requestId;
3498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303499 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303501}
3502
3503
3504static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3505{
3506 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3507 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303508 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303510 ENTER();
3511
3512 if (wlan_hdd_validate_context(pHddCtx)){
3513 return;
3514 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303515
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303516 if (!pMsg)
3517 {
3518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 return;
3520 }
3521
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303522 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3523 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303525 context = &pHddCtx->ext_scan_context;
3526 spin_lock(&hdd_context_lock);
3527 if (context->request_id == pData->requestId) {
3528 context->response_status = pData->status ? -EINVAL : 0;
3529 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303531 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535}
3536
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3538 void *pMsg)
3539{
3540 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 tpSirEXTScanSetBssidHotListRspParams pData =
3542 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303543 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303545 ENTER();
3546
3547 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548 return;
3549 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303550
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303551 if (!pMsg)
3552 {
3553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3554 return;
3555 }
3556
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303557 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3558 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303560 context = &pHddCtx->ext_scan_context;
3561 spin_lock(&hdd_context_lock);
3562 if (context->request_id == pData->requestId) {
3563 context->response_status = pData->status ? -EINVAL : 0;
3564 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303566 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303569 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570}
3571
3572static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3573 void *pMsg)
3574{
3575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 tpSirEXTScanResetBssidHotlistRspParams pData =
3577 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303578 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303580 ENTER();
3581
3582 if (wlan_hdd_validate_context(pHddCtx)) {
3583 return;
3584 }
3585 if (!pMsg)
3586 {
3587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303588 return;
3589 }
3590
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303591 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3592 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303593
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303594 context = &pHddCtx->ext_scan_context;
3595 spin_lock(&hdd_context_lock);
3596 if (context->request_id == pData->requestId) {
3597 context->response_status = pData->status ? -EINVAL : 0;
3598 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303600 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303602 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604}
3605
Dino Mycle6fb96c12014-06-10 11:52:40 +05303606static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3607 void *pMsg)
3608{
3609 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3610 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303611 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303612 tANI_S32 totalResults;
3613 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3615 struct hdd_ext_scan_context *context;
3616 bool ignore_cached_results = false;
3617 tExtscanCachedScanResult *result;
3618 struct nlattr *nla_results;
3619 tANI_U16 ieLength= 0;
3620 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303622 ENTER();
3623
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303624 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303627 if (!pMsg)
3628 {
3629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3630 return;
3631 }
3632
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303633 spin_lock(&hdd_context_lock);
3634 context = &pHddCtx->ext_scan_context;
3635 ignore_cached_results = context->ignore_cached_results;
3636 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303638 if (ignore_cached_results) {
3639 hddLog(LOGE,
3640 FL("Ignore the cached results received after timeout"));
3641 return;
3642 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303644 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3645 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303647 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303648
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3650 scan_id_index++) {
3651 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303653 totalResults = result->num_results;
3654 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3655 result->scan_id, result->flags, totalResults);
3656 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303658 do{
3659 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3660 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3661 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303663 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3664 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3665
3666 if (!skb) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR,
3668 FL("cfg80211_vendor_event_alloc failed"));
3669 return;
3670 }
3671
3672 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3673
3674 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3675 pData->requestId) ||
3676 nla_put_u32(skb,
3677 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3678 resultsPerEvent)) {
3679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3680 goto fail;
3681 }
3682 if (nla_put_u8(skb,
3683 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3684 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 {
3686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3687 goto fail;
3688 }
3689
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303690 if (nla_put_u32(skb,
3691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3692 result->scan_id)) {
3693 hddLog(LOGE, FL("put fail"));
3694 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303696
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303697 nla_results = nla_nest_start(skb,
3698 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3699 if (!nla_results)
3700 goto fail;
3701
3702 if (resultsPerEvent) {
3703 struct nlattr *aps;
3704 struct nlattr *nla_result;
3705
3706 nla_result = nla_nest_start(skb, scan_id_index);
3707 if(!nla_result)
3708 goto fail;
3709
3710 if (nla_put_u32(skb,
3711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3712 result->scan_id) ||
3713 nla_put_u32(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3715 result->flags) ||
3716 nla_put_u32(skb,
3717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3718 totalResults)) {
3719 hddLog(LOGE, FL("put fail"));
3720 goto fail;
3721 }
3722
3723 aps = nla_nest_start(skb,
3724 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3725 if (!aps)
3726 {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3728 goto fail;
3729 }
3730
3731 head_ptr = (tpSirWifiScanResult) &(result->ap);
3732
3733 for (j = 0; j < resultsPerEvent; j++, i++) {
3734 struct nlattr *ap;
3735 pSirWifiScanResult = head_ptr + i;
3736
3737 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303738 * Firmware returns timestamp from extscan_start till
3739 * BSSID was cached (in micro seconds). Add this with
3740 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303741 * to derive the time since boot when the
3742 * BSSID was cached.
3743 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303744 pSirWifiScanResult->ts +=
3745 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303746 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3747 "Ssid (%s)"
3748 "Bssid: %pM "
3749 "Channel (%u)"
3750 "Rssi (%d)"
3751 "RTT (%u)"
3752 "RTT_SD (%u)"
3753 "Beacon Period %u"
3754 "Capability 0x%x "
3755 "Ie length %d",
3756 i,
3757 pSirWifiScanResult->ts,
3758 pSirWifiScanResult->ssid,
3759 pSirWifiScanResult->bssid,
3760 pSirWifiScanResult->channel,
3761 pSirWifiScanResult->rssi,
3762 pSirWifiScanResult->rtt,
3763 pSirWifiScanResult->rtt_sd,
3764 pSirWifiScanResult->beaconPeriod,
3765 pSirWifiScanResult->capability,
3766 ieLength);
3767
3768 ap = nla_nest_start(skb, j + 1);
3769 if (!ap)
3770 {
3771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3772 goto fail;
3773 }
3774
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303775 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303776 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3777 pSirWifiScanResult->ts) )
3778 {
3779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3780 goto fail;
3781 }
3782 if (nla_put(skb,
3783 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3784 sizeof(pSirWifiScanResult->ssid),
3785 pSirWifiScanResult->ssid) )
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3788 goto fail;
3789 }
3790 if (nla_put(skb,
3791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3792 sizeof(pSirWifiScanResult->bssid),
3793 pSirWifiScanResult->bssid) )
3794 {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3796 goto fail;
3797 }
3798 if (nla_put_u32(skb,
3799 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3800 pSirWifiScanResult->channel) )
3801 {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3803 goto fail;
3804 }
3805 if (nla_put_s32(skb,
3806 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3807 pSirWifiScanResult->rssi) )
3808 {
3809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3810 goto fail;
3811 }
3812 if (nla_put_u32(skb,
3813 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3814 pSirWifiScanResult->rtt) )
3815 {
3816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3817 goto fail;
3818 }
3819 if (nla_put_u32(skb,
3820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3821 pSirWifiScanResult->rtt_sd))
3822 {
3823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3824 goto fail;
3825 }
3826 if (nla_put_u32(skb,
3827 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3828 pSirWifiScanResult->beaconPeriod))
3829 {
3830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3831 goto fail;
3832 }
3833 if (nla_put_u32(skb,
3834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3835 pSirWifiScanResult->capability))
3836 {
3837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3838 goto fail;
3839 }
3840 if (nla_put_u32(skb,
3841 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3842 ieLength))
3843 {
3844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3845 goto fail;
3846 }
3847
3848 if (ieLength)
3849 if (nla_put(skb,
3850 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3851 ieLength, ie)) {
3852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3853 goto fail;
3854 }
3855
3856 nla_nest_end(skb, ap);
3857 }
3858 nla_nest_end(skb, aps);
3859 nla_nest_end(skb, nla_result);
3860 }
3861
3862 nla_nest_end(skb, nla_results);
3863
3864 cfg80211_vendor_cmd_reply(skb);
3865
3866 } while (totalResults > 0);
3867 }
3868
3869 if (!pData->moreData) {
3870 spin_lock(&hdd_context_lock);
3871 context->response_status = 0;
3872 complete(&context->response_event);
3873 spin_unlock(&hdd_context_lock);
3874 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303876 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303877 return;
3878fail:
3879 kfree_skb(skb);
3880 return;
3881}
3882
3883static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3884 void *pMsg)
3885{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303886 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303887 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3888 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303889 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303891 ENTER();
3892
3893 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303894 hddLog(LOGE,
3895 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303896 return;
3897 }
3898 if (!pMsg)
3899 {
3900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 return;
3902 }
3903
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303904 if (pData->bss_found)
3905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3906 else
3907 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3908
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3911 NULL,
3912#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303914 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
3916 if (!skb) {
3917 hddLog(VOS_TRACE_LEVEL_ERROR,
3918 FL("cfg80211_vendor_event_alloc failed"));
3919 return;
3920 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303922 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3923 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3924 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3925 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3926
3927 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303928 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3929 "Ssid (%s) "
3930 "Bssid (" MAC_ADDRESS_STR ") "
3931 "Channel (%u) "
3932 "Rssi (%d) "
3933 "RTT (%u) "
3934 "RTT_SD (%u) ",
3935 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303936 pData->bssHotlist[i].ts,
3937 pData->bssHotlist[i].ssid,
3938 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3939 pData->bssHotlist[i].channel,
3940 pData->bssHotlist[i].rssi,
3941 pData->bssHotlist[i].rtt,
3942 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943 }
3944
3945 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3946 pData->requestId) ||
3947 nla_put_u32(skb,
3948 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3951 goto fail;
3952 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303953 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303954 struct nlattr *aps;
3955
3956 aps = nla_nest_start(skb,
3957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3958 if (!aps)
3959 goto fail;
3960
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303962 struct nlattr *ap;
3963
3964 ap = nla_nest_start(skb, i + 1);
3965 if (!ap)
3966 goto fail;
3967
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303968 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303970 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303971 nla_put(skb,
3972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303973 sizeof(pData->bssHotlist[i].ssid),
3974 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303975 nla_put(skb,
3976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303977 sizeof(pData->bssHotlist[i].bssid),
3978 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 nla_put_u32(skb,
3980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303981 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 nla_put_s32(skb,
3983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303984 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303987 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303988 nla_put_u32(skb,
3989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303990 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303991 goto fail;
3992
3993 nla_nest_end(skb, ap);
3994 }
3995 nla_nest_end(skb, aps);
3996
3997 if (nla_put_u8(skb,
3998 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3999 pData->moreData))
4000 goto fail;
4001 }
4002
4003 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304004 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005 return;
4006
4007fail:
4008 kfree_skb(skb);
4009 return;
4010
4011}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304012
4013static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4014 void *pMsg)
4015{
4016 struct sk_buff *skb;
4017 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4018 tpSirWifiFullScanResultEvent pData =
4019 (tpSirWifiFullScanResultEvent) (pMsg);
4020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304021 ENTER();
4022
4023 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304024 hddLog(LOGE,
4025 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304026 return;
4027 }
4028 if (!pMsg)
4029 {
4030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 return;
4032 }
4033
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304034 /*
4035 * If the full scan result including IE data exceeds NL 4K size
4036 * limitation, drop that beacon/probe rsp frame.
4037 */
4038 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4039 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4040 return;
4041 }
4042
Dino Mycle6fb96c12014-06-10 11:52:40 +05304043 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4045 NULL,
4046#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304047 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4048 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4049 GFP_KERNEL);
4050
4051 if (!skb) {
4052 hddLog(VOS_TRACE_LEVEL_ERROR,
4053 FL("cfg80211_vendor_event_alloc failed"));
4054 return;
4055 }
4056
Dino Mycle6fb96c12014-06-10 11:52:40 +05304057 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4059 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4060 "Ssid (%s)"
4061 "Bssid (" MAC_ADDRESS_STR ")"
4062 "Channel (%u)"
4063 "Rssi (%d)"
4064 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304065 "RTT_SD (%u)"
4066 "Bcn Period %d"
4067 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304068 pData->ap.ts,
4069 pData->ap.ssid,
4070 MAC_ADDR_ARRAY(pData->ap.bssid),
4071 pData->ap.channel,
4072 pData->ap.rssi,
4073 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304074 pData->ap.rtt_sd,
4075 pData->ap.beaconPeriod,
4076 pData->ap.capability);
4077
Dino Mycle6fb96c12014-06-10 11:52:40 +05304078 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4079 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4080 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304081 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4083 pData->ap.ts) ||
4084 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4085 sizeof(pData->ap.ssid),
4086 pData->ap.ssid) ||
4087 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4088 WNI_CFG_BSSID_LEN,
4089 pData->ap.bssid) ||
4090 nla_put_u32(skb,
4091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4092 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304093 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304094 pData->ap.rssi) ||
4095 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4096 pData->ap.rtt) ||
4097 nla_put_u32(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4099 pData->ap.rtt_sd) ||
4100 nla_put_u16(skb,
4101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4102 pData->ap.beaconPeriod) ||
4103 nla_put_u16(skb,
4104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4105 pData->ap.capability) ||
4106 nla_put_u32(skb,
4107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304108 pData->ieLength) ||
4109 nla_put_u8(skb,
4110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4111 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304112 {
4113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4114 goto nla_put_failure;
4115 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304116
4117 if (pData->ieLength) {
4118 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4119 pData->ieLength,
4120 pData->ie))
4121 {
4122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4123 goto nla_put_failure;
4124 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304125 }
4126
4127 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304128 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304129 return;
4130
4131nla_put_failure:
4132 kfree_skb(skb);
4133 return;
4134}
4135
4136static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4137 void *pMsg)
4138{
4139 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4140 struct sk_buff *skb = NULL;
4141 tpSirEXTScanResultsAvailableIndParams pData =
4142 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304144 ENTER();
4145
4146 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304147 hddLog(LOGE,
4148 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304149 return;
4150 }
4151 if (!pMsg)
4152 {
4153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304154 return;
4155 }
4156
4157 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4159 NULL,
4160#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304161 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4162 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4163 GFP_KERNEL);
4164
4165 if (!skb) {
4166 hddLog(VOS_TRACE_LEVEL_ERROR,
4167 FL("cfg80211_vendor_event_alloc failed"));
4168 return;
4169 }
4170
Dino Mycle6fb96c12014-06-10 11:52:40 +05304171 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4172 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4173 pData->numResultsAvailable);
4174 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4175 pData->requestId) ||
4176 nla_put_u32(skb,
4177 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4178 pData->numResultsAvailable)) {
4179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4180 goto nla_put_failure;
4181 }
4182
4183 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304184 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304185 return;
4186
4187nla_put_failure:
4188 kfree_skb(skb);
4189 return;
4190}
4191
4192static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4193{
4194 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4195 struct sk_buff *skb = NULL;
4196 tpSirEXTScanProgressIndParams pData =
4197 (tpSirEXTScanProgressIndParams) pMsg;
4198
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304199 ENTER();
4200
4201 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304202 hddLog(LOGE,
4203 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304204 return;
4205 }
4206 if (!pMsg)
4207 {
4208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209 return;
4210 }
4211
4212 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304213#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4214 NULL,
4215#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4217 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4218 GFP_KERNEL);
4219
4220 if (!skb) {
4221 hddLog(VOS_TRACE_LEVEL_ERROR,
4222 FL("cfg80211_vendor_event_alloc failed"));
4223 return;
4224 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304225 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4227 pData->extScanEventType);
4228 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4229 pData->status);
4230
4231 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4232 pData->extScanEventType) ||
4233 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4235 pData->requestId) ||
4236 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304237 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4238 pData->status)) {
4239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4240 goto nla_put_failure;
4241 }
4242
4243 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304244 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 return;
4246
4247nla_put_failure:
4248 kfree_skb(skb);
4249 return;
4250}
4251
4252void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4253 void *pMsg)
4254{
4255 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304257 ENTER();
4258
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260 return;
4261 }
4262
4263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4264
4265
4266 switch(evType) {
4267 case SIR_HAL_EXTSCAN_START_RSP:
4268 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4269 break;
4270
4271 case SIR_HAL_EXTSCAN_STOP_RSP:
4272 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4273 break;
4274 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4275 /* There is no need to send this response to upper layer
4276 Just log the message */
4277 hddLog(VOS_TRACE_LEVEL_INFO,
4278 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4279 break;
4280 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4281 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4282 break;
4283
4284 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4285 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4286 break;
4287
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304289 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304290 break;
4291 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4292 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4293 break;
4294 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4295 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4296 break;
4297 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4298 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4299 break;
4300 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4301 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4302 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4304 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4305 break;
4306 default:
4307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4308 break;
4309 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304310 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304311}
4312
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304313static bool wlan_hdd_is_extscan_supported(hdd_adapter_t *adapter,
4314 hdd_context_t *hdd_ctx)
4315{
4316 int status;
4317
4318 status = wlan_hdd_validate_context(hdd_ctx);
4319 if (status)
4320 return false;
4321
4322 if (!adapter) {
4323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid adapter"));
4324 return false;
4325 }
4326
4327 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
4328 hddLog(VOS_TRACE_LEVEL_INFO,
4329 FL("ext scans only supported on STA ifaces"));
4330 return false;
4331 }
4332
4333 if (VOS_FTM_MODE == hdd_get_conparam()) {
4334 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4335 return false;
4336 }
4337
4338 /* check the EXTScan Capability */
4339 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4340 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4341 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR,
4343 FL("EXTScan not enabled/supported by Firmware"));
4344 return false;
4345 }
4346 return true;
4347}
4348
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304349static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4350 struct wireless_dev *wdev,
4351 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352{
Dino Myclee8843b32014-07-04 14:21:45 +05304353 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354 struct net_device *dev = wdev->netdev;
4355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4356 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4357 struct nlattr
4358 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4359 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304360 struct hdd_ext_scan_context *context;
4361 unsigned long rc;
4362 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304364 ENTER();
4365
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304366 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304367 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304368
Dino Mycle6fb96c12014-06-10 11:52:40 +05304369 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4370 data, dataLen,
4371 wlan_hdd_extscan_config_policy)) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4373 return -EINVAL;
4374 }
4375
4376 /* Parse and fetch request Id */
4377 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4379 return -EINVAL;
4380 }
4381
Dino Myclee8843b32014-07-04 14:21:45 +05304382 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304383 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304384 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304385
Dino Myclee8843b32014-07-04 14:21:45 +05304386 reqMsg.sessionId = pAdapter->sessionId;
4387 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304389 vos_spin_lock_acquire(&hdd_context_lock);
4390 context = &pHddCtx->ext_scan_context;
4391 context->request_id = reqMsg.requestId;
4392 INIT_COMPLETION(context->response_event);
4393 vos_spin_lock_release(&hdd_context_lock);
4394
Dino Myclee8843b32014-07-04 14:21:45 +05304395 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 if (!HAL_STATUS_SUCCESS(status)) {
4397 hddLog(VOS_TRACE_LEVEL_ERROR,
4398 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399 return -EINVAL;
4400 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304401
4402 rc = wait_for_completion_timeout(&context->response_event,
4403 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4404 if (!rc) {
4405 hddLog(LOGE, FL("Target response timed out"));
4406 return -ETIMEDOUT;
4407 }
4408
4409 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4410 if (ret)
4411 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4412
4413 return ret;
4414
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304415 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304416 return 0;
4417}
4418
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304419static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4420 struct wireless_dev *wdev,
4421 const void *data, int dataLen)
4422{
4423 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304424
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304425 vos_ssr_protect(__func__);
4426 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4427 vos_ssr_unprotect(__func__);
4428
4429 return ret;
4430}
4431
4432static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4433 struct wireless_dev *wdev,
4434 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304435{
Dino Myclee8843b32014-07-04 14:21:45 +05304436 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304437 struct net_device *dev = wdev->netdev;
4438 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4439 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4440 struct nlattr
4441 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4442 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304443 struct hdd_ext_scan_context *context;
4444 unsigned long rc;
4445 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304447 ENTER();
4448
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304449 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304450 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304451
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4453 data, dataLen,
4454 wlan_hdd_extscan_config_policy)) {
4455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4456 return -EINVAL;
4457 }
4458 /* Parse and fetch request Id */
4459 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4461 return -EINVAL;
4462 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304463
Dino Myclee8843b32014-07-04 14:21:45 +05304464 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304465 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4466
Dino Myclee8843b32014-07-04 14:21:45 +05304467 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304468
Dino Myclee8843b32014-07-04 14:21:45 +05304469 reqMsg.sessionId = pAdapter->sessionId;
4470 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304471
4472 /* Parse and fetch flush parameter */
4473 if (!tb
4474 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4475 {
4476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4477 goto failed;
4478 }
Dino Myclee8843b32014-07-04 14:21:45 +05304479 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304480 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4481
Dino Myclee8843b32014-07-04 14:21:45 +05304482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304483
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304484 spin_lock(&hdd_context_lock);
4485 context = &pHddCtx->ext_scan_context;
4486 context->request_id = reqMsg.requestId;
4487 context->ignore_cached_results = false;
4488 INIT_COMPLETION(context->response_event);
4489 spin_unlock(&hdd_context_lock);
4490
Dino Myclee8843b32014-07-04 14:21:45 +05304491 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304492 if (!HAL_STATUS_SUCCESS(status)) {
4493 hddLog(VOS_TRACE_LEVEL_ERROR,
4494 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495 return -EINVAL;
4496 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304497
4498 rc = wait_for_completion_timeout(&context->response_event,
4499 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4500 if (!rc) {
4501 hddLog(LOGE, FL("Target response timed out"));
4502 retval = -ETIMEDOUT;
4503 spin_lock(&hdd_context_lock);
4504 context->ignore_cached_results = true;
4505 spin_unlock(&hdd_context_lock);
4506 } else {
4507 spin_lock(&hdd_context_lock);
4508 retval = context->response_status;
4509 spin_unlock(&hdd_context_lock);
4510 }
4511
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304512 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304513 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304514
4515failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304516 return -EINVAL;
4517}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304518static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4519 struct wireless_dev *wdev,
4520 const void *data, int dataLen)
4521{
4522 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304523
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304524 vos_ssr_protect(__func__);
4525 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4526 vos_ssr_unprotect(__func__);
4527
4528 return ret;
4529}
4530
4531static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304533 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304534{
4535 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4536 struct net_device *dev = wdev->netdev;
4537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4538 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4539 struct nlattr
4540 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4541 struct nlattr
4542 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4543 struct nlattr *apTh;
4544 eHalStatus status;
4545 tANI_U8 i = 0;
4546 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304547 struct hdd_ext_scan_context *context;
4548 tANI_U32 request_id;
4549 unsigned long rc;
4550 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304552 ENTER();
4553
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304554 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304555 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304556
Dino Mycle6fb96c12014-06-10 11:52:40 +05304557 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4558 data, dataLen,
4559 wlan_hdd_extscan_config_policy)) {
4560 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4561 return -EINVAL;
4562 }
4563
4564 /* Parse and fetch request Id */
4565 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4567 return -EINVAL;
4568 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304569 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4570 vos_mem_malloc(sizeof(*pReqMsg));
4571 if (!pReqMsg) {
4572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4573 return -ENOMEM;
4574 }
4575
Dino Myclee8843b32014-07-04 14:21:45 +05304576
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577 pReqMsg->requestId = nla_get_u32(
4578 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4579 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4580
4581 /* Parse and fetch number of APs */
4582 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4584 goto fail;
4585 }
4586
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304587 /* Parse and fetch lost ap sample size */
4588 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4589 hddLog(LOGE, FL("attr lost ap sample size failed"));
4590 goto fail;
4591 }
4592
4593 pReqMsg->lostBssidSampleSize = nla_get_u32(
4594 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4595 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4596
Dino Mycle6fb96c12014-06-10 11:52:40 +05304597 pReqMsg->sessionId = pAdapter->sessionId;
4598 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4599
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304600 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304601 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304602 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4603 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4604 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4605 goto fail;
4606 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304607 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608
4609 nla_for_each_nested(apTh,
4610 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304611 if (i == pReqMsg->numBssid) {
4612 hddLog(LOGW, FL("Ignoring excess AP"));
4613 break;
4614 }
4615
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4617 nla_data(apTh), nla_len(apTh),
4618 NULL)) {
4619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4620 goto fail;
4621 }
4622
4623 /* Parse and fetch MAC address */
4624 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4626 goto fail;
4627 }
4628 memcpy(pReqMsg->ap[i].bssid, nla_data(
4629 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4630 sizeof(tSirMacAddr));
4631 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4632
4633 /* Parse and fetch low RSSI */
4634 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4636 goto fail;
4637 }
4638 pReqMsg->ap[i].low = nla_get_s32(
4639 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4640 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4641
4642 /* Parse and fetch high RSSI */
4643 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4645 goto fail;
4646 }
4647 pReqMsg->ap[i].high = nla_get_s32(
4648 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4649 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4650 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 i++;
4652 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304653
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304654 if (i < pReqMsg->numBssid) {
4655 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4656 i, pReqMsg->numBssid);
4657 pReqMsg->numBssid = i;
4658 }
4659
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304660 context = &pHddCtx->ext_scan_context;
4661 spin_lock(&hdd_context_lock);
4662 INIT_COMPLETION(context->response_event);
4663 context->request_id = request_id = pReqMsg->requestId;
4664 spin_unlock(&hdd_context_lock);
4665
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4667 if (!HAL_STATUS_SUCCESS(status)) {
4668 hddLog(VOS_TRACE_LEVEL_ERROR,
4669 FL("sme_SetBssHotlist failed(err=%d)"), status);
4670 vos_mem_free(pReqMsg);
4671 return -EINVAL;
4672 }
4673
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304674 /* request was sent -- wait for the response */
4675 rc = wait_for_completion_timeout(&context->response_event,
4676 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4677
4678 if (!rc) {
4679 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4680 retval = -ETIMEDOUT;
4681 } else {
4682 spin_lock(&hdd_context_lock);
4683 if (context->request_id == request_id)
4684 retval = context->response_status;
4685 else
4686 retval = -EINVAL;
4687 spin_unlock(&hdd_context_lock);
4688 }
4689
Dino Myclee8843b32014-07-04 14:21:45 +05304690 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304691 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304692 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304693
4694fail:
4695 vos_mem_free(pReqMsg);
4696 return -EINVAL;
4697}
4698
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304699static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4700 struct wireless_dev *wdev,
4701 const void *data, int dataLen)
4702{
4703 int ret = 0;
4704
4705 vos_ssr_protect(__func__);
4706 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4707 dataLen);
4708 vos_ssr_unprotect(__func__);
4709
4710 return ret;
4711}
4712
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304713static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304715 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304717 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4718 struct net_device *dev = wdev->netdev;
4719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4720 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4721 uint8_t num_channels = 0;
4722 uint8_t num_chan_new = 0;
4723 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304725 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304726 tWifiBand wifiBand;
4727 eHalStatus status;
4728 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304729 tANI_U8 i,j,k;
4730 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304732 ENTER();
4733
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304734 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304736
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4738 data, dataLen,
4739 wlan_hdd_extscan_config_policy)) {
4740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4741 return -EINVAL;
4742 }
4743
4744 /* Parse and fetch request Id */
4745 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4747 return -EINVAL;
4748 }
4749 requestId = nla_get_u32(
4750 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4752
4753 /* Parse and fetch wifi band */
4754 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4755 {
4756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4757 return -EINVAL;
4758 }
4759 wifiBand = nla_get_u32(
4760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4762
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304763 /* Parse and fetch max channels */
4764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4765 {
4766 hddLog(LOGE, FL("attr max channels failed"));
4767 return -EINVAL;
4768 }
4769 maxChannels = nla_get_u32(
4770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4772
Dino Mycle6fb96c12014-06-10 11:52:40 +05304773 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304774 wifiBand, chan_list,
4775 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304776 if (eHAL_STATUS_SUCCESS != status) {
4777 hddLog(VOS_TRACE_LEVEL_ERROR,
4778 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4779 return -EINVAL;
4780 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304781
Agrawal Ashish16abf782016-08-18 22:42:59 +05304782 num_channels = VOS_MIN(num_channels, maxChannels);
4783 num_chan_new = num_channels;
4784 /* remove the indoor only channels if iface is SAP */
4785 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4786 {
4787 num_chan_new = 0;
4788 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304789 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304790 if (wiphy->bands[j] == NULL)
4791 continue;
4792 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4793 if ((chan_list[i] ==
4794 wiphy->bands[j]->channels[k].center_freq) &&
4795 (!(wiphy->bands[j]->channels[k].flags &
4796 IEEE80211_CHAN_INDOOR_ONLY))) {
4797 chan_list[num_chan_new] = chan_list[i];
4798 num_chan_new++;
4799 }
4800 }
4801 }
4802 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304803
Agrawal Ashish16abf782016-08-18 22:42:59 +05304804 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4805 for (i = 0; i < num_chan_new; i++)
4806 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4807 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808
4809 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304810 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 NLMSG_HDRLEN);
4812
4813 if (!replySkb) {
4814 hddLog(VOS_TRACE_LEVEL_ERROR,
4815 FL("valid channels: buffer alloc fail"));
4816 return -EINVAL;
4817 }
4818 if (nla_put_u32(replySkb,
4819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304820 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304822 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823
4824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4825 kfree_skb(replySkb);
4826 return -EINVAL;
4827 }
4828
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304829 ret = cfg80211_vendor_cmd_reply(replySkb);
4830
4831 EXIT();
4832 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833}
4834
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304835static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4836 struct wireless_dev *wdev,
4837 const void *data, int dataLen)
4838{
4839 int ret = 0;
4840
4841 vos_ssr_protect(__func__);
4842 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4843 dataLen);
4844 vos_ssr_unprotect(__func__);
4845
4846 return ret;
4847}
4848
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304849static int hdd_extscan_start_fill_bucket_channel_spec(
4850 hdd_context_t *pHddCtx,
4851 tpSirEXTScanStartReqParams pReqMsg,
4852 struct nlattr **tb)
4853{
4854 struct nlattr *bucket[
4855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4856 struct nlattr *channel[
4857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4858 struct nlattr *buckets;
4859 struct nlattr *channels;
4860 int rem1, rem2;
4861 eHalStatus status;
4862 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304863 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304864 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4865 tANI_U32 passive_max_chn_time, active_max_chn_time;
4866
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304867 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304868 bktIndex = 0;
4869
4870 nla_for_each_nested(buckets,
4871 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304872 if (bktIndex >= expected_buckets) {
4873 hddLog(LOGW, FL("ignoring excess buckets"));
4874 break;
4875 }
4876
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304877 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304878 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4879 nla_data(buckets), nla_len(buckets),
4880 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304881 hddLog(LOGE, FL("nla_parse failed"));
4882 return -EINVAL;
4883 }
4884
4885 /* Parse and fetch bucket spec */
4886 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4887 hddLog(LOGE, FL("attr bucket index failed"));
4888 return -EINVAL;
4889 }
4890 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4891 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4892 hddLog(LOG1, FL("Bucket spec Index %d"),
4893 pReqMsg->buckets[bktIndex].bucket);
4894
4895 /* Parse and fetch wifi band */
4896 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4897 hddLog(LOGE, FL("attr wifi band failed"));
4898 return -EINVAL;
4899 }
4900 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4901 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4902 hddLog(LOG1, FL("Wifi band %d"),
4903 pReqMsg->buckets[bktIndex].band);
4904
4905 /* Parse and fetch period */
4906 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4907 hddLog(LOGE, FL("attr period failed"));
4908 return -EINVAL;
4909 }
4910 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4911 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4912 hddLog(LOG1, FL("period %d"),
4913 pReqMsg->buckets[bktIndex].period);
4914
4915 /* Parse and fetch report events */
4916 if (!bucket[
4917 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4918 hddLog(LOGE, FL("attr report events failed"));
4919 return -EINVAL;
4920 }
4921 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4922 bucket[
4923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4924 hddLog(LOG1, FL("report events %d"),
4925 pReqMsg->buckets[bktIndex].reportEvents);
4926
4927 /* Parse and fetch max period */
4928 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4929 hddLog(LOGE, FL("attr max period failed"));
4930 return -EINVAL;
4931 }
4932 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4933 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4934 hddLog(LOG1, FL("max period %u"),
4935 pReqMsg->buckets[bktIndex].max_period);
4936
4937 /* Parse and fetch exponent */
4938 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4939 hddLog(LOGE, FL("attr exponent failed"));
4940 return -EINVAL;
4941 }
4942 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4943 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4944 hddLog(LOG1, FL("exponent %u"),
4945 pReqMsg->buckets[bktIndex].exponent);
4946
4947 /* Parse and fetch step count */
4948 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4949 hddLog(LOGE, FL("attr step count failed"));
4950 return -EINVAL;
4951 }
4952 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4953 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4954 hddLog(LOG1, FL("Step count %u"),
4955 pReqMsg->buckets[bktIndex].step_count);
4956
4957 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4959
4960 /* Framework shall pass the channel list if the input WiFi band is
4961 * WIFI_BAND_UNSPECIFIED.
4962 * If the input WiFi band is specified (any value other than
4963 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4964 */
4965 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4966 numChannels = 0;
4967 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4968 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4969 pReqMsg->buckets[bktIndex].band,
4970 chanList, &numChannels);
4971 if (!HAL_STATUS_SUCCESS(status)) {
4972 hddLog(LOGE,
4973 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4974 status);
4975 return -EINVAL;
4976 }
4977
4978 pReqMsg->buckets[bktIndex].numChannels =
4979 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4980 hddLog(LOG1, FL("Num channels %d"),
4981 pReqMsg->buckets[bktIndex].numChannels);
4982
4983 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4984 j++) {
4985 pReqMsg->buckets[bktIndex].channels[j].channel =
4986 chanList[j];
4987 pReqMsg->buckets[bktIndex].channels[j].
4988 chnlClass = 0;
4989 if (CSR_IS_CHANNEL_DFS(
4990 vos_freq_to_chan(chanList[j]))) {
4991 pReqMsg->buckets[bktIndex].channels[j].
4992 passive = 1;
4993 pReqMsg->buckets[bktIndex].channels[j].
4994 dwellTimeMs = passive_max_chn_time;
4995 } else {
4996 pReqMsg->buckets[bktIndex].channels[j].
4997 passive = 0;
4998 pReqMsg->buckets[bktIndex].channels[j].
4999 dwellTimeMs = active_max_chn_time;
5000 }
5001
5002 hddLog(LOG1,
5003 "Channel %u Passive %u Dwell time %u ms",
5004 pReqMsg->buckets[bktIndex].channels[j].channel,
5005 pReqMsg->buckets[bktIndex].channels[j].passive,
5006 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5007 }
5008
5009 bktIndex++;
5010 continue;
5011 }
5012
5013 /* Parse and fetch number of channels */
5014 if (!bucket[
5015 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5016 hddLog(LOGE, FL("attr num channels failed"));
5017 return -EINVAL;
5018 }
5019
5020 pReqMsg->buckets[bktIndex].numChannels =
5021 nla_get_u32(bucket[
5022 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5023 hddLog(LOG1, FL("num channels %d"),
5024 pReqMsg->buckets[bktIndex].numChannels);
5025
5026 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5027 hddLog(LOGE, FL("attr channel spec failed"));
5028 return -EINVAL;
5029 }
5030
5031 j = 0;
5032 nla_for_each_nested(channels,
5033 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5034 if (nla_parse(channel,
5035 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5036 nla_data(channels), nla_len(channels),
5037 wlan_hdd_extscan_config_policy)) {
5038 hddLog(LOGE, FL("nla_parse failed"));
5039 return -EINVAL;
5040 }
5041
5042 /* Parse and fetch channel */
5043 if (!channel[
5044 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5045 hddLog(LOGE, FL("attr channel failed"));
5046 return -EINVAL;
5047 }
5048 pReqMsg->buckets[bktIndex].channels[j].channel =
5049 nla_get_u32(channel[
5050 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5051 hddLog(LOG1, FL("channel %u"),
5052 pReqMsg->buckets[bktIndex].channels[j].channel);
5053
5054 /* Parse and fetch dwell time */
5055 if (!channel[
5056 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5057 hddLog(LOGE, FL("attr dwelltime failed"));
5058 return -EINVAL;
5059 }
5060 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5061 nla_get_u32(channel[
5062 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5063
5064 hddLog(LOG1, FL("Dwell time (%u ms)"),
5065 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5066
5067
5068 /* Parse and fetch channel spec passive */
5069 if (!channel[
5070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5071 hddLog(LOGE,
5072 FL("attr channel spec passive failed"));
5073 return -EINVAL;
5074 }
5075 pReqMsg->buckets[bktIndex].channels[j].passive =
5076 nla_get_u8(channel[
5077 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5078 hddLog(LOG1, FL("Chnl spec passive %u"),
5079 pReqMsg->buckets[bktIndex].channels[j].passive);
5080
5081 j++;
5082 }
5083
5084 bktIndex++;
5085 }
5086
5087 return 0;
5088}
5089
5090
5091/*
5092 * define short names for the global vendor params
5093 * used by wlan_hdd_cfg80211_extscan_start()
5094 */
5095#define PARAM_MAX \
5096QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5097#define PARAM_REQUEST_ID \
5098QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5099#define PARAM_BASE_PERIOD \
5100QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5101#define PARAM_MAX_AP_PER_SCAN \
5102QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5103#define PARAM_RPT_THRHLD_PERCENT \
5104QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5105#define PARAM_RPT_THRHLD_NUM_SCANS \
5106QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5107#define PARAM_NUM_BUCKETS \
5108QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5109
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305110static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305111 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305112 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305113{
Dino Myclee8843b32014-07-04 14:21:45 +05305114 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305115 struct net_device *dev = wdev->netdev;
5116 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5117 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5118 struct nlattr *tb[PARAM_MAX + 1];
5119 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305120 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305121 tANI_U32 request_id;
5122 struct hdd_ext_scan_context *context;
5123 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305125 ENTER();
5126
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305127 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305129
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305130 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305131 data, dataLen,
5132 wlan_hdd_extscan_config_policy)) {
5133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5134 return -EINVAL;
5135 }
5136
5137 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305138 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5140 return -EINVAL;
5141 }
5142
Dino Myclee8843b32014-07-04 14:21:45 +05305143 pReqMsg = (tpSirEXTScanStartReqParams)
5144 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5147 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305148 }
5149
5150 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305151 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305152 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5153
5154 pReqMsg->sessionId = pAdapter->sessionId;
5155 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5156
5157 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305158 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5160 goto fail;
5161 }
5162 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305163 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305164 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5165 pReqMsg->basePeriod);
5166
5167 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305168 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5170 goto fail;
5171 }
5172 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305173 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5175 pReqMsg->maxAPperScan);
5176
5177 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5180 goto fail;
5181 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305182 pReqMsg->reportThresholdPercent = nla_get_u8(
5183 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305185 pReqMsg->reportThresholdPercent);
5186
5187 /* Parse and fetch report threshold num scans */
5188 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5189 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5190 goto fail;
5191 }
5192 pReqMsg->reportThresholdNumScans = nla_get_u8(
5193 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5194 hddLog(LOG1, FL("Report Threshold num scans %d"),
5195 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196
5197 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305198 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5200 goto fail;
5201 }
5202 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305204 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5205 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5206 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5207 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5208 }
5209 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5210 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305211
Dino Mycle6fb96c12014-06-10 11:52:40 +05305212 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5214 goto fail;
5215 }
5216
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305217 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305218
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305219 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5220 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305221
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305222 context = &pHddCtx->ext_scan_context;
5223 spin_lock(&hdd_context_lock);
5224 INIT_COMPLETION(context->response_event);
5225 context->request_id = request_id = pReqMsg->requestId;
5226 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305227
Dino Mycle6fb96c12014-06-10 11:52:40 +05305228 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5229 if (!HAL_STATUS_SUCCESS(status)) {
5230 hddLog(VOS_TRACE_LEVEL_ERROR,
5231 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305232 goto fail;
5233 }
5234
Srinivas Dasari91727c12016-03-23 17:59:06 +05305235 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 /* request was sent -- wait for the response */
5238 rc = wait_for_completion_timeout(&context->response_event,
5239 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5240
5241 if (!rc) {
5242 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5243 retval = -ETIMEDOUT;
5244 } else {
5245 spin_lock(&hdd_context_lock);
5246 if (context->request_id == request_id)
5247 retval = context->response_status;
5248 else
5249 retval = -EINVAL;
5250 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305251 }
5252
Dino Myclee8843b32014-07-04 14:21:45 +05305253 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305254 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256
5257fail:
5258 vos_mem_free(pReqMsg);
5259 return -EINVAL;
5260}
5261
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305262/*
5263 * done with short names for the global vendor params
5264 * used by wlan_hdd_cfg80211_extscan_start()
5265 */
5266#undef PARAM_MAX
5267#undef PARAM_REQUEST_ID
5268#undef PARAM_BASE_PERIOD
5269#undef PARAMS_MAX_AP_PER_SCAN
5270#undef PARAMS_RPT_THRHLD_PERCENT
5271#undef PARAMS_RPT_THRHLD_NUM_SCANS
5272#undef PARAMS_NUM_BUCKETS
5273
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305274static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5275 struct wireless_dev *wdev,
5276 const void *data, int dataLen)
5277{
5278 int ret = 0;
5279
5280 vos_ssr_protect(__func__);
5281 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5282 vos_ssr_unprotect(__func__);
5283
5284 return ret;
5285}
5286
5287static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305288 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305289 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305290{
Dino Myclee8843b32014-07-04 14:21:45 +05305291 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305292 struct net_device *dev = wdev->netdev;
5293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5294 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5295 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5296 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305297 int retval;
5298 unsigned long rc;
5299 struct hdd_ext_scan_context *context;
5300 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305301
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305302 ENTER();
5303
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305304 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305305 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305306
Dino Mycle6fb96c12014-06-10 11:52:40 +05305307 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5308 data, dataLen,
5309 wlan_hdd_extscan_config_policy)) {
5310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5311 return -EINVAL;
5312 }
5313
5314 /* Parse and fetch request Id */
5315 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5317 return -EINVAL;
5318 }
5319
Dino Myclee8843b32014-07-04 14:21:45 +05305320 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305321 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305322 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305323
Dino Myclee8843b32014-07-04 14:21:45 +05305324 reqMsg.sessionId = pAdapter->sessionId;
5325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305326
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305327 context = &pHddCtx->ext_scan_context;
5328 spin_lock(&hdd_context_lock);
5329 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305330 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305331 spin_unlock(&hdd_context_lock);
5332
Dino Myclee8843b32014-07-04 14:21:45 +05305333 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305334 if (!HAL_STATUS_SUCCESS(status)) {
5335 hddLog(VOS_TRACE_LEVEL_ERROR,
5336 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305337 return -EINVAL;
5338 }
5339
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305340 /* request was sent -- wait for the response */
5341 rc = wait_for_completion_timeout(&context->response_event,
5342 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5343
5344 if (!rc) {
5345 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5346 retval = -ETIMEDOUT;
5347 } else {
5348 spin_lock(&hdd_context_lock);
5349 if (context->request_id == request_id)
5350 retval = context->response_status;
5351 else
5352 retval = -EINVAL;
5353 spin_unlock(&hdd_context_lock);
5354 }
5355
5356 return retval;
5357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305358 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305359 return 0;
5360}
5361
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305362static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5363 struct wireless_dev *wdev,
5364 const void *data, int dataLen)
5365{
5366 int ret = 0;
5367
5368 vos_ssr_protect(__func__);
5369 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5370 vos_ssr_unprotect(__func__);
5371
5372 return ret;
5373}
5374
5375static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305376 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305377 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378{
Dino Myclee8843b32014-07-04 14:21:45 +05305379 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305380 struct net_device *dev = wdev->netdev;
5381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5382 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5383 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5384 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305385 struct hdd_ext_scan_context *context;
5386 tANI_U32 request_id;
5387 unsigned long rc;
5388 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305389
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305390 ENTER();
5391
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305392 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305393 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305394
Dino Mycle6fb96c12014-06-10 11:52:40 +05305395 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5396 data, dataLen,
5397 wlan_hdd_extscan_config_policy)) {
5398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5399 return -EINVAL;
5400 }
5401
5402 /* Parse and fetch request Id */
5403 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5405 return -EINVAL;
5406 }
5407
Dino Myclee8843b32014-07-04 14:21:45 +05305408 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305409 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305410 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411
Dino Myclee8843b32014-07-04 14:21:45 +05305412 reqMsg.sessionId = pAdapter->sessionId;
5413 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305414
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305415 context = &pHddCtx->ext_scan_context;
5416 spin_lock(&hdd_context_lock);
5417 INIT_COMPLETION(context->response_event);
5418 context->request_id = request_id = reqMsg.requestId;
5419 spin_unlock(&hdd_context_lock);
5420
Dino Myclee8843b32014-07-04 14:21:45 +05305421 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305422 if (!HAL_STATUS_SUCCESS(status)) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR,
5424 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305425 return -EINVAL;
5426 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427
5428 /* request was sent -- wait for the response */
5429 rc = wait_for_completion_timeout(&context->response_event,
5430 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5431 if (!rc) {
5432 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5433 retval = -ETIMEDOUT;
5434 } else {
5435 spin_lock(&hdd_context_lock);
5436 if (context->request_id == request_id)
5437 retval = context->response_status;
5438 else
5439 retval = -EINVAL;
5440 spin_unlock(&hdd_context_lock);
5441 }
5442
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305443 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305444 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305445}
5446
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305447static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5448 struct wireless_dev *wdev,
5449 const void *data, int dataLen)
5450{
5451 int ret = 0;
5452
5453 vos_ssr_protect(__func__);
5454 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5455 vos_ssr_unprotect(__func__);
5456
5457 return ret;
5458}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305459#endif /* WLAN_FEATURE_EXTSCAN */
5460
Atul Mittal115287b2014-07-08 13:26:33 +05305461/*EXT TDLS*/
5462static const struct nla_policy
5463wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5464{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305465 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5466 .type = NLA_UNSPEC,
5467 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305468 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5469 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5470 {.type = NLA_S32 },
5471 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5472 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5473
5474};
5475
5476static const struct nla_policy
5477wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5478{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305479 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5480 .type = NLA_UNSPEC,
5481 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305482
5483};
5484
5485static const struct nla_policy
5486wlan_hdd_tdls_config_state_change_policy[
5487 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5488{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305489 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5490 .type = NLA_UNSPEC,
5491 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305492 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5493 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305494 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5495 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5496 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305497
5498};
5499
5500static const struct nla_policy
5501wlan_hdd_tdls_config_get_status_policy[
5502 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5503{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305504 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5505 .type = NLA_UNSPEC,
5506 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305507 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5508 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305509 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5510 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5511 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305512
5513};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305514
5515static const struct nla_policy
5516wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5519 .type = NLA_UNSPEC,
5520 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305521};
5522
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305523static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305524 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305525 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305526 int data_len)
5527{
5528
5529 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5530 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305532 ENTER();
5533
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305534 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305535 return -EINVAL;
5536 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305537 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305538 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305539 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305540 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305541 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305542 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305543 return -ENOTSUPP;
5544 }
5545
5546 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5547 data, data_len, wlan_hdd_mac_config)) {
5548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5549 return -EINVAL;
5550 }
5551
5552 /* Parse and fetch mac address */
5553 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5555 return -EINVAL;
5556 }
5557
5558 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5559 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5560 VOS_MAC_ADDR_LAST_3_BYTES);
5561
Siddharth Bhal76972212014-10-15 16:22:51 +05305562 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5563
5564 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305565 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5566 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305567 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5568 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5569 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5570 {
5571 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5572 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5573 VOS_MAC_ADDRESS_LEN);
5574 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305575 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305576
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305577 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5578 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305580 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305581 return 0;
5582}
5583
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305584static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5585 struct wireless_dev *wdev,
5586 const void *data,
5587 int data_len)
5588{
5589 int ret = 0;
5590
5591 vos_ssr_protect(__func__);
5592 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5593 vos_ssr_unprotect(__func__);
5594
5595 return ret;
5596}
5597
5598static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305599 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305600 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305601 int data_len)
5602{
5603 u8 peer[6] = {0};
5604 struct net_device *dev = wdev->netdev;
5605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5607 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5608 eHalStatus ret;
5609 tANI_S32 state;
5610 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305611 tANI_S32 global_operating_class = 0;
5612 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305613 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305614 int retVal;
5615
5616 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305617
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305618 if (!pAdapter) {
5619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5620 return -EINVAL;
5621 }
5622
Atul Mittal115287b2014-07-08 13:26:33 +05305623 ret = wlan_hdd_validate_context(pHddCtx);
5624 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305626 return -EINVAL;
5627 }
5628 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305630 return -ENOTSUPP;
5631 }
5632 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5633 data, data_len,
5634 wlan_hdd_tdls_config_get_status_policy)) {
5635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5636 return -EINVAL;
5637 }
5638
5639 /* Parse and fetch mac address */
5640 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5642 return -EINVAL;
5643 }
5644
5645 memcpy(peer, nla_data(
5646 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5647 sizeof(peer));
5648 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5649
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305650 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305651
Atul Mittal115287b2014-07-08 13:26:33 +05305652 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305653 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305654 NLMSG_HDRLEN);
5655
5656 if (!skb) {
5657 hddLog(VOS_TRACE_LEVEL_ERROR,
5658 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5659 return -EINVAL;
5660 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305661 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 +05305662 reason,
5663 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 global_operating_class,
5665 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305666 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305667 if (nla_put_s32(skb,
5668 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5669 state) ||
5670 nla_put_s32(skb,
5671 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5672 reason) ||
5673 nla_put_s32(skb,
5674 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5675 global_operating_class) ||
5676 nla_put_s32(skb,
5677 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5678 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305679
5680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5681 goto nla_put_failure;
5682 }
5683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305684 retVal = cfg80211_vendor_cmd_reply(skb);
5685 EXIT();
5686 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305687
5688nla_put_failure:
5689 kfree_skb(skb);
5690 return -EINVAL;
5691}
5692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305693static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5694 struct wireless_dev *wdev,
5695 const void *data,
5696 int data_len)
5697{
5698 int ret = 0;
5699
5700 vos_ssr_protect(__func__);
5701 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5702 vos_ssr_unprotect(__func__);
5703
5704 return ret;
5705}
5706
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305707static int wlan_hdd_cfg80211_exttdls_callback(
5708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5709 const tANI_U8* mac,
5710#else
5711 tANI_U8* mac,
5712#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305713 tANI_S32 state,
5714 tANI_S32 reason,
5715 void *ctx)
5716{
5717 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305718 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305719 tANI_S32 global_operating_class = 0;
5720 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305721 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305722
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305723 ENTER();
5724
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305725 if (!pAdapter) {
5726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5727 return -EINVAL;
5728 }
5729
5730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305731 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305733 return -EINVAL;
5734 }
5735
5736 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305738 return -ENOTSUPP;
5739 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305740 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5742 NULL,
5743#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305744 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5745 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5746 GFP_KERNEL);
5747
5748 if (!skb) {
5749 hddLog(VOS_TRACE_LEVEL_ERROR,
5750 FL("cfg80211_vendor_event_alloc failed"));
5751 return -EINVAL;
5752 }
5753 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305754 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5755 reason,
5756 state,
5757 global_operating_class,
5758 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305759 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5760 MAC_ADDR_ARRAY(mac));
5761
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305762 if (nla_put(skb,
5763 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5764 VOS_MAC_ADDR_SIZE, mac) ||
5765 nla_put_s32(skb,
5766 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5767 state) ||
5768 nla_put_s32(skb,
5769 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5770 reason) ||
5771 nla_put_s32(skb,
5772 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5773 channel) ||
5774 nla_put_s32(skb,
5775 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5776 global_operating_class)
5777 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5779 goto nla_put_failure;
5780 }
5781
5782 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305783 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305784 return (0);
5785
5786nla_put_failure:
5787 kfree_skb(skb);
5788 return -EINVAL;
5789}
5790
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305791static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305792 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305793 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305794 int data_len)
5795{
5796 u8 peer[6] = {0};
5797 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305798 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5799 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5800 eHalStatus status;
5801 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305802 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305803 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305804
5805 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305806
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305807 if (!dev) {
5808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5809 return -EINVAL;
5810 }
5811
5812 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5813 if (!pAdapter) {
5814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5815 return -EINVAL;
5816 }
5817
Atul Mittal115287b2014-07-08 13:26:33 +05305818 status = wlan_hdd_validate_context(pHddCtx);
5819 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305821 return -EINVAL;
5822 }
5823 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305825 return -ENOTSUPP;
5826 }
5827 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5828 data, data_len,
5829 wlan_hdd_tdls_config_enable_policy)) {
5830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5831 return -EINVAL;
5832 }
5833
5834 /* Parse and fetch mac address */
5835 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5836 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5837 return -EINVAL;
5838 }
5839
5840 memcpy(peer, nla_data(
5841 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5842 sizeof(peer));
5843 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5844
5845 /* Parse and fetch channel */
5846 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5848 return -EINVAL;
5849 }
5850 pReqMsg.channel = nla_get_s32(
5851 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5852 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5853
5854 /* Parse and fetch global operating class */
5855 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5857 return -EINVAL;
5858 }
5859 pReqMsg.global_operating_class = nla_get_s32(
5860 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5862 pReqMsg.global_operating_class);
5863
5864 /* Parse and fetch latency ms */
5865 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5867 return -EINVAL;
5868 }
5869 pReqMsg.max_latency_ms = nla_get_s32(
5870 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5872 pReqMsg.max_latency_ms);
5873
5874 /* Parse and fetch required bandwidth kbps */
5875 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5877 return -EINVAL;
5878 }
5879
5880 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5881 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5882 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5883 pReqMsg.min_bandwidth_kbps);
5884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305885 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305886 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305887 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305888 wlan_hdd_cfg80211_exttdls_callback);
5889
5890 EXIT();
5891 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305892}
5893
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305894static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data,
5897 int data_len)
5898{
5899 int ret = 0;
5900
5901 vos_ssr_protect(__func__);
5902 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5903 vos_ssr_unprotect(__func__);
5904
5905 return ret;
5906}
5907
5908static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305909 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305910 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305911 int data_len)
5912{
5913 u8 peer[6] = {0};
5914 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5916 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5917 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305918 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305919 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305920
5921 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305922
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305923 if (!dev) {
5924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5925 return -EINVAL;
5926 }
5927
5928 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5929 if (!pAdapter) {
5930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5931 return -EINVAL;
5932 }
5933
Atul Mittal115287b2014-07-08 13:26:33 +05305934 status = wlan_hdd_validate_context(pHddCtx);
5935 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305937 return -EINVAL;
5938 }
5939 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305941 return -ENOTSUPP;
5942 }
5943 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5944 data, data_len,
5945 wlan_hdd_tdls_config_disable_policy)) {
5946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5947 return -EINVAL;
5948 }
5949 /* Parse and fetch mac address */
5950 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5952 return -EINVAL;
5953 }
5954
5955 memcpy(peer, nla_data(
5956 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5957 sizeof(peer));
5958 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305960 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5961
5962 EXIT();
5963 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305964}
5965
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305966static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5967 struct wireless_dev *wdev,
5968 const void *data,
5969 int data_len)
5970{
5971 int ret = 0;
5972
5973 vos_ssr_protect(__func__);
5974 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5975 vos_ssr_unprotect(__func__);
5976
5977 return ret;
5978}
5979
Dasari Srinivas7875a302014-09-26 17:50:57 +05305980static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305981__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305982 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305983 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305984{
5985 struct net_device *dev = wdev->netdev;
5986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5987 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5988 struct sk_buff *skb = NULL;
5989 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305990 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305991
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305992 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305993
5994 ret = wlan_hdd_validate_context(pHddCtx);
5995 if (0 != ret)
5996 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305997 return ret;
5998 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305999 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6000 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6001 fset |= WIFI_FEATURE_INFRA;
6002 }
6003
6004 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6005 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6006 fset |= WIFI_FEATURE_INFRA_5G;
6007 }
6008
6009#ifdef WLAN_FEATURE_P2P
6010 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6011 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6012 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6013 fset |= WIFI_FEATURE_P2P;
6014 }
6015#endif
6016
6017 /* Soft-AP is supported currently by default */
6018 fset |= WIFI_FEATURE_SOFT_AP;
6019
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306020 /* HOTSPOT is a supplicant feature, enable it by default */
6021 fset |= WIFI_FEATURE_HOTSPOT;
6022
Dasari Srinivas7875a302014-09-26 17:50:57 +05306023#ifdef WLAN_FEATURE_EXTSCAN
6024 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306025 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6026 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6027 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306028 fset |= WIFI_FEATURE_EXTSCAN;
6029 }
6030#endif
6031
Dasari Srinivas7875a302014-09-26 17:50:57 +05306032 if (sme_IsFeatureSupportedByFW(NAN)) {
6033 hddLog(LOG1, FL("NAN is supported by firmware"));
6034 fset |= WIFI_FEATURE_NAN;
6035 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306036
6037 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306038 if (sme_IsFeatureSupportedByFW(RTT) &&
6039 pHddCtx->cfg_ini->enable_rtt_support) {
6040 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306041 fset |= WIFI_FEATURE_D2AP_RTT;
6042 }
6043
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306044 if (sme_IsFeatureSupportedByFW(RTT3)) {
6045 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6046 fset |= WIFI_FEATURE_RTT3;
6047 }
6048
Dasari Srinivas7875a302014-09-26 17:50:57 +05306049#ifdef FEATURE_WLAN_BATCH_SCAN
6050 if (fset & WIFI_FEATURE_EXTSCAN) {
6051 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6052 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6053 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6054 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6055 fset |= WIFI_FEATURE_BATCH_SCAN;
6056 }
6057#endif
6058
6059#ifdef FEATURE_WLAN_SCAN_PNO
6060 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6061 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6062 hddLog(LOG1, FL("PNO is supported by firmware"));
6063 fset |= WIFI_FEATURE_PNO;
6064 }
6065#endif
6066
6067 /* STA+STA is supported currently by default */
6068 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6069
6070#ifdef FEATURE_WLAN_TDLS
6071 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6072 sme_IsFeatureSupportedByFW(TDLS)) {
6073 hddLog(LOG1, FL("TDLS is supported by firmware"));
6074 fset |= WIFI_FEATURE_TDLS;
6075 }
6076
6077 /* TDLS_OFFCHANNEL is not supported currently by default */
6078#endif
6079
6080#ifdef WLAN_AP_STA_CONCURRENCY
6081 /* AP+STA concurrency is supported currently by default */
6082 fset |= WIFI_FEATURE_AP_STA;
6083#endif
6084
Mukul Sharma5add0532015-08-17 15:57:47 +05306085#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306086 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6087 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306088 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6089 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306090 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306091#endif
6092
Dasari Srinivas7875a302014-09-26 17:50:57 +05306093 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6094 NLMSG_HDRLEN);
6095
6096 if (!skb) {
6097 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6098 return -EINVAL;
6099 }
6100 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6101
6102 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6103 hddLog(LOGE, FL("nla put fail"));
6104 goto nla_put_failure;
6105 }
6106
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306107 ret = cfg80211_vendor_cmd_reply(skb);
6108 EXIT();
6109 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306110
6111nla_put_failure:
6112 kfree_skb(skb);
6113 return -EINVAL;
6114}
6115
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306116static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306117wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6118 struct wireless_dev *wdev,
6119 const void *data, int data_len)
6120{
6121 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306122 vos_ssr_protect(__func__);
6123 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6124 vos_ssr_unprotect(__func__);
6125
6126 return ret;
6127}
6128
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306129
6130static const struct
6131nla_policy
6132qca_wlan_vendor_wifi_logger_get_ring_data_policy
6133[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6134 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6135 = {.type = NLA_U32 },
6136};
6137
6138static int
6139 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6140 struct wireless_dev *wdev,
6141 const void *data,
6142 int data_len)
6143{
6144 int ret;
6145 VOS_STATUS status;
6146 uint32_t ring_id;
6147 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6148 struct nlattr *tb
6149 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6150
6151 ENTER();
6152
6153 ret = wlan_hdd_validate_context(hdd_ctx);
6154 if (0 != ret) {
6155 return ret;
6156 }
6157
6158 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6159 data, data_len,
6160 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6161 hddLog(LOGE, FL("Invalid attribute"));
6162 return -EINVAL;
6163 }
6164
6165 /* Parse and fetch ring id */
6166 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6167 hddLog(LOGE, FL("attr ATTR failed"));
6168 return -EINVAL;
6169 }
6170
6171 ring_id = nla_get_u32(
6172 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6173
6174 hddLog(LOG1, FL("Bug report triggered by framework"));
6175
6176 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6177 WLAN_LOG_INDICATOR_FRAMEWORK,
6178 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306179 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306180 );
6181 if (VOS_STATUS_SUCCESS != status) {
6182 hddLog(LOGE, FL("Failed to trigger bug report"));
6183
6184 return -EINVAL;
6185 }
6186
6187 return 0;
6188
6189
6190}
6191
6192
6193static int
6194 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6195 struct wireless_dev *wdev,
6196 const void *data,
6197 int data_len)
6198{
6199 int ret = 0;
6200
6201 vos_ssr_protect(__func__);
6202 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6203 wdev, data, data_len);
6204 vos_ssr_unprotect(__func__);
6205
6206 return ret;
6207
6208}
6209
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306210#define MAX_CONCURRENT_MATRIX \
6211 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6212#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6213 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6214static const struct nla_policy
6215wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6216 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6217};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306218
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306219static int
6220__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306221 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306222 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306223{
6224 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6225 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306226 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306227 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306228 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6229 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306230
6231 ENTER();
6232
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306233 ret = wlan_hdd_validate_context(pHddCtx);
6234 if (0 != ret)
6235 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306236 return ret;
6237 }
6238
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306239 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6240 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306241 hddLog(LOGE, FL("Invalid ATTR"));
6242 return -EINVAL;
6243 }
6244
6245 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306246 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306247 hddLog(LOGE, FL("Attr max feature set size failed"));
6248 return -EINVAL;
6249 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306250 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306251 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6252
6253 /* Fill feature combination matrix */
6254 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306255 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6256 WIFI_FEATURE_P2P;
6257
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306258 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6259 WIFI_FEATURE_SOFT_AP;
6260
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306261 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6262 WIFI_FEATURE_SOFT_AP;
6263
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306264 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6265 WIFI_FEATURE_SOFT_AP |
6266 WIFI_FEATURE_P2P;
6267
6268 /* Add more feature combinations here */
6269
6270 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6271 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6272 hddLog(LOG1, "Feature set matrix");
6273 for (i = 0; i < feature_sets; i++)
6274 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6275
6276 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6277 sizeof(u32) * feature_sets +
6278 NLMSG_HDRLEN);
6279
6280 if (reply_skb) {
6281 if (nla_put_u32(reply_skb,
6282 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6283 feature_sets) ||
6284 nla_put(reply_skb,
6285 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6286 sizeof(u32) * feature_sets, feature_set_matrix)) {
6287 hddLog(LOGE, FL("nla put fail"));
6288 kfree_skb(reply_skb);
6289 return -EINVAL;
6290 }
6291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306292 ret = cfg80211_vendor_cmd_reply(reply_skb);
6293 EXIT();
6294 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306295 }
6296 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6297 return -ENOMEM;
6298
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306299}
6300
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306301#undef MAX_CONCURRENT_MATRIX
6302#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6303
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306304static int
6305wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6306 struct wireless_dev *wdev,
6307 const void *data, int data_len)
6308{
6309 int ret = 0;
6310
6311 vos_ssr_protect(__func__);
6312 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6313 data_len);
6314 vos_ssr_unprotect(__func__);
6315
6316 return ret;
6317}
6318
c_manjeecfd1efb2015-09-25 19:32:34 +05306319
6320static int
6321__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6322 struct wireless_dev *wdev,
6323 const void *data, int data_len)
6324{
6325 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6326 int ret;
6327 ENTER();
6328
6329 ret = wlan_hdd_validate_context(pHddCtx);
6330 if (0 != ret)
6331 {
6332 return ret;
6333 }
6334
6335 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6336 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6337 {
6338 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306339 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306340 }
6341 /*call common API for FW mem dump req*/
6342 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6343
Abhishek Singhc783fa72015-12-09 18:07:34 +05306344 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306345 {
6346 /*indicate to userspace the status of fw mem dump */
6347 wlan_indicate_mem_dump_complete(true);
6348 }
6349 else
6350 {
6351 /*else send failure to userspace */
6352 wlan_indicate_mem_dump_complete(false);
6353 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306354 EXIT();
6355 return ret;
6356}
6357
6358/**
6359 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6360 * @wiphy: pointer to wireless wiphy structure.
6361 * @wdev: pointer to wireless_dev structure.
6362 * @data: Pointer to the NL data.
6363 * @data_len:Length of @data
6364 *
6365 * This is called when wlan driver needs to get the firmware memory dump
6366 * via vendor specific command.
6367 *
6368 * Return: 0 on success, error number otherwise.
6369 */
6370
6371static int
6372wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6373 struct wireless_dev *wdev,
6374 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306375{
6376 int ret = 0;
6377 vos_ssr_protect(__func__);
6378 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6379 data_len);
6380 vos_ssr_unprotect(__func__);
6381 return ret;
6382}
c_manjeecfd1efb2015-09-25 19:32:34 +05306383
Sushant Kaushik8e644982015-09-23 12:18:54 +05306384static const struct
6385nla_policy
6386qca_wlan_vendor_wifi_logger_start_policy
6387[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6388 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6389 = {.type = NLA_U32 },
6390 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6391 = {.type = NLA_U32 },
6392 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6393 = {.type = NLA_U32 },
6394};
6395
6396/**
6397 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6398 * or disable the collection of packet statistics from the firmware
6399 * @wiphy: WIPHY structure pointer
6400 * @wdev: Wireless device structure pointer
6401 * @data: Pointer to the data received
6402 * @data_len: Length of the data received
6403 *
6404 * This function is used to enable or disable the collection of packet
6405 * statistics from the firmware
6406 *
6407 * Return: 0 on success and errno on failure
6408 */
6409static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6410 struct wireless_dev *wdev,
6411 const void *data,
6412 int data_len)
6413{
6414 eHalStatus status;
6415 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6416 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6417 tAniWifiStartLog start_log;
6418
6419 status = wlan_hdd_validate_context(hdd_ctx);
6420 if (0 != status) {
6421 return -EINVAL;
6422 }
6423
6424 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6425 data, data_len,
6426 qca_wlan_vendor_wifi_logger_start_policy)) {
6427 hddLog(LOGE, FL("Invalid attribute"));
6428 return -EINVAL;
6429 }
6430
6431 /* Parse and fetch ring id */
6432 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6433 hddLog(LOGE, FL("attr ATTR failed"));
6434 return -EINVAL;
6435 }
6436 start_log.ringId = nla_get_u32(
6437 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6438 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6439
6440 /* Parse and fetch verbose level */
6441 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6442 hddLog(LOGE, FL("attr verbose_level failed"));
6443 return -EINVAL;
6444 }
6445 start_log.verboseLevel = nla_get_u32(
6446 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6447 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6448
6449 /* Parse and fetch flag */
6450 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6451 hddLog(LOGE, FL("attr flag failed"));
6452 return -EINVAL;
6453 }
6454 start_log.flag = nla_get_u32(
6455 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6456 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6457
6458 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306459 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6460 !vos_isPktStatsEnabled()))
6461
Sushant Kaushik8e644982015-09-23 12:18:54 +05306462 {
6463 hddLog(LOGE, FL("per pkt stats not enabled"));
6464 return -EINVAL;
6465 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306466
Sushant Kaushik33200572015-08-05 16:46:20 +05306467 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306468 return 0;
6469}
6470
6471/**
6472 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6473 * or disable the collection of packet statistics from the firmware
6474 * @wiphy: WIPHY structure pointer
6475 * @wdev: Wireless device structure pointer
6476 * @data: Pointer to the data received
6477 * @data_len: Length of the data received
6478 *
6479 * This function is used to enable or disable the collection of packet
6480 * statistics from the firmware
6481 *
6482 * Return: 0 on success and errno on failure
6483 */
6484static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6485 struct wireless_dev *wdev,
6486 const void *data,
6487 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306488{
6489 int ret = 0;
6490
6491 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306492
6493 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6494 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306495 vos_ssr_unprotect(__func__);
6496
6497 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306498}
6499
6500
Agarwal Ashish738843c2014-09-25 12:27:56 +05306501static const struct nla_policy
6502wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6503 +1] =
6504{
6505 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6506};
6507
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306508static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306509 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306510 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306511 int data_len)
6512{
6513 struct net_device *dev = wdev->netdev;
6514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6515 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6516 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6517 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6518 eHalStatus status;
6519 u32 dfsFlag = 0;
6520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306521 ENTER();
6522
Agarwal Ashish738843c2014-09-25 12:27:56 +05306523 status = wlan_hdd_validate_context(pHddCtx);
6524 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306525 return -EINVAL;
6526 }
6527 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6528 data, data_len,
6529 wlan_hdd_set_no_dfs_flag_config_policy)) {
6530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6531 return -EINVAL;
6532 }
6533
6534 /* Parse and fetch required bandwidth kbps */
6535 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6537 return -EINVAL;
6538 }
6539
6540 dfsFlag = nla_get_u32(
6541 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6542 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6543 dfsFlag);
6544
6545 pHddCtx->disable_dfs_flag = dfsFlag;
6546
6547 sme_disable_dfs_channel(hHal, dfsFlag);
6548 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306549
6550 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306551 return 0;
6552}
Atul Mittal115287b2014-07-08 13:26:33 +05306553
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306554static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6555 struct wireless_dev *wdev,
6556 const void *data,
6557 int data_len)
6558{
6559 int ret = 0;
6560
6561 vos_ssr_protect(__func__);
6562 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6563 vos_ssr_unprotect(__func__);
6564
6565 return ret;
6566
6567}
6568
Mukul Sharma2a271632014-10-13 14:59:01 +05306569const struct
6570nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6571{
6572 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306573 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6574 .type = NLA_UNSPEC,
6575 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306576};
6577
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306578static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306579 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306580{
6581
6582 u8 bssid[6] = {0};
6583 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6584 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6585 eHalStatus status = eHAL_STATUS_SUCCESS;
6586 v_U32_t isFwrRoamEnabled = FALSE;
6587 int ret;
6588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306589 ENTER();
6590
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306591 ret = wlan_hdd_validate_context(pHddCtx);
6592 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306593 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306594 }
6595
6596 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6597 data, data_len,
6598 qca_wlan_vendor_attr);
6599 if (ret){
6600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6601 return -EINVAL;
6602 }
6603
6604 /* Parse and fetch Enable flag */
6605 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6607 return -EINVAL;
6608 }
6609
6610 isFwrRoamEnabled = nla_get_u32(
6611 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6612
6613 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6614
6615 /* Parse and fetch bssid */
6616 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6618 return -EINVAL;
6619 }
6620
6621 memcpy(bssid, nla_data(
6622 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6623 sizeof(bssid));
6624 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6625
6626 //Update roaming
6627 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306628 if (!HAL_STATUS_SUCCESS(status)) {
6629 hddLog(LOGE,
6630 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6631 return -EINVAL;
6632 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306633 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306634 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306635}
6636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306637static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6638 struct wireless_dev *wdev, const void *data, int data_len)
6639{
6640 int ret = 0;
6641
6642 vos_ssr_protect(__func__);
6643 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6644 vos_ssr_unprotect(__func__);
6645
6646 return ret;
6647}
6648
Sushant Kaushik847890c2015-09-28 16:05:17 +05306649static const struct
6650nla_policy
6651qca_wlan_vendor_get_wifi_info_policy[
6652 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6653 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6654 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6655};
6656
6657
6658/**
6659 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6660 * @wiphy: pointer to wireless wiphy structure.
6661 * @wdev: pointer to wireless_dev structure.
6662 * @data: Pointer to the data to be passed via vendor interface
6663 * @data_len:Length of the data to be passed
6664 *
6665 * This is called when wlan driver needs to send wifi driver related info
6666 * (driver/fw version) to the user space application upon request.
6667 *
6668 * Return: Return the Success or Failure code.
6669 */
6670static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6671 struct wireless_dev *wdev,
6672 const void *data, int data_len)
6673{
6674 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6675 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6676 tSirVersionString version;
6677 uint32 version_len;
6678 uint8 attr;
6679 int status;
6680 struct sk_buff *reply_skb = NULL;
6681
6682 if (VOS_FTM_MODE == hdd_get_conparam()) {
6683 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6684 return -EINVAL;
6685 }
6686
6687 status = wlan_hdd_validate_context(hdd_ctx);
6688 if (0 != status) {
6689 hddLog(LOGE, FL("HDD context is not valid"));
6690 return -EINVAL;
6691 }
6692
6693 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6694 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6695 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6696 return -EINVAL;
6697 }
6698
6699 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6700 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6701 QWLAN_VERSIONSTR);
6702 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6703 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6704 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6705 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6706 hdd_ctx->fw_Version);
6707 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6708 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6709 } else {
6710 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6711 return -EINVAL;
6712 }
6713
6714 version_len = strlen(version);
6715 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6716 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6717 if (!reply_skb) {
6718 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6719 return -ENOMEM;
6720 }
6721
6722 if (nla_put(reply_skb, attr, version_len, version)) {
6723 hddLog(LOGE, FL("nla put fail"));
6724 kfree_skb(reply_skb);
6725 return -EINVAL;
6726 }
6727
6728 return cfg80211_vendor_cmd_reply(reply_skb);
6729}
6730
6731/**
6732 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6733 * @wiphy: pointer to wireless wiphy structure.
6734 * @wdev: pointer to wireless_dev structure.
6735 * @data: Pointer to the data to be passed via vendor interface
6736 * @data_len:Length of the data to be passed
6737 * @data_len: Length of the data received
6738 *
6739 * This function is used to enable or disable the collection of packet
6740 * statistics from the firmware
6741 *
6742 * Return: 0 on success and errno on failure
6743 */
6744
6745static int
6746wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6747 struct wireless_dev *wdev,
6748 const void *data, int data_len)
6749
6750
6751{
6752 int ret = 0;
6753
6754 vos_ssr_protect(__func__);
6755 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6756 wdev, data, data_len);
6757 vos_ssr_unprotect(__func__);
6758
6759 return ret;
6760}
6761
6762
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306763/*
6764 * define short names for the global vendor params
6765 * used by __wlan_hdd_cfg80211_monitor_rssi()
6766 */
6767#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6768#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6769#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6770#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6771#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6772
6773/**---------------------------------------------------------------------------
6774
6775 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6776 monitor start is completed successfully.
6777
6778 \return - None
6779
6780 --------------------------------------------------------------------------*/
6781void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6782{
6783 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6784
6785 if (NULL == pHddCtx)
6786 {
6787 hddLog(VOS_TRACE_LEVEL_ERROR,
6788 "%s: HDD context is NULL",__func__);
6789 return;
6790 }
6791
6792 if (VOS_STATUS_SUCCESS == status)
6793 {
6794 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6795 }
6796 else
6797 {
6798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6799 }
6800
6801 return;
6802}
6803
6804/**---------------------------------------------------------------------------
6805
6806 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6807 stop is completed successfully.
6808
6809 \return - None
6810
6811 --------------------------------------------------------------------------*/
6812void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6813{
6814 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6815
6816 if (NULL == pHddCtx)
6817 {
6818 hddLog(VOS_TRACE_LEVEL_ERROR,
6819 "%s: HDD context is NULL",__func__);
6820 return;
6821 }
6822
6823 if (VOS_STATUS_SUCCESS == status)
6824 {
6825 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6826 }
6827 else
6828 {
6829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6830 }
6831
6832 return;
6833}
6834
6835/**
6836 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6837 * @wiphy: Pointer to wireless phy
6838 * @wdev: Pointer to wireless device
6839 * @data: Pointer to data
6840 * @data_len: Data length
6841 *
6842 * Return: 0 on success, negative errno on failure
6843 */
6844
6845static int
6846__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6847 struct wireless_dev *wdev,
6848 const void *data,
6849 int data_len)
6850{
6851 struct net_device *dev = wdev->netdev;
6852 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6853 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6854 hdd_station_ctx_t *pHddStaCtx;
6855 struct nlattr *tb[PARAM_MAX + 1];
6856 tpSirRssiMonitorReq pReq;
6857 eHalStatus status;
6858 int ret;
6859 uint32_t control;
6860 static const struct nla_policy policy[PARAM_MAX + 1] = {
6861 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6862 [PARAM_CONTROL] = { .type = NLA_U32 },
6863 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6864 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6865 };
6866
6867 ENTER();
6868
6869 ret = wlan_hdd_validate_context(hdd_ctx);
6870 if (0 != ret) {
6871 return -EINVAL;
6872 }
6873
6874 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6875 hddLog(LOGE, FL("Not in Connected state!"));
6876 return -ENOTSUPP;
6877 }
6878
6879 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6880 hddLog(LOGE, FL("Invalid ATTR"));
6881 return -EINVAL;
6882 }
6883
6884 if (!tb[PARAM_REQUEST_ID]) {
6885 hddLog(LOGE, FL("attr request id failed"));
6886 return -EINVAL;
6887 }
6888
6889 if (!tb[PARAM_CONTROL]) {
6890 hddLog(LOGE, FL("attr control failed"));
6891 return -EINVAL;
6892 }
6893
6894 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6895
6896 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6897 if(NULL == pReq)
6898 {
6899 hddLog(LOGE,
6900 FL("vos_mem_alloc failed "));
6901 return eHAL_STATUS_FAILED_ALLOC;
6902 }
6903 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6904
6905 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6906 pReq->sessionId = pAdapter->sessionId;
6907 pReq->rssiMonitorCbContext = hdd_ctx;
6908 control = nla_get_u32(tb[PARAM_CONTROL]);
6909 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6910
6911 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6912 pReq->requestId, pReq->sessionId, control);
6913
6914 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6915 if (!tb[PARAM_MIN_RSSI]) {
6916 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306917 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306918 }
6919
6920 if (!tb[PARAM_MAX_RSSI]) {
6921 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306922 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306923 }
6924
6925 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6926 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6927 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6928
6929 if (!(pReq->minRssi < pReq->maxRssi)) {
6930 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6931 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306932 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306933 }
6934 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6935 pReq->minRssi, pReq->maxRssi);
6936 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6937
6938 }
6939 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6940 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6941 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6942 }
6943 else {
6944 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306945 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306946 }
6947
6948 if (!HAL_STATUS_SUCCESS(status)) {
6949 hddLog(LOGE,
6950 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306951 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306952 }
6953
6954 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306955fail:
6956 vos_mem_free(pReq);
6957 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306958}
6959
6960/*
6961 * done with short names for the global vendor params
6962 * used by __wlan_hdd_cfg80211_monitor_rssi()
6963 */
6964#undef PARAM_MAX
6965#undef PARAM_CONTROL
6966#undef PARAM_REQUEST_ID
6967#undef PARAM_MAX_RSSI
6968#undef PARAM_MIN_RSSI
6969
6970/**
6971 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6972 * @wiphy: wiphy structure pointer
6973 * @wdev: Wireless device structure pointer
6974 * @data: Pointer to the data received
6975 * @data_len: Length of @data
6976 *
6977 * Return: 0 on success; errno on failure
6978 */
6979static int
6980wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6981 const void *data, int data_len)
6982{
6983 int ret;
6984
6985 vos_ssr_protect(__func__);
6986 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6987 vos_ssr_unprotect(__func__);
6988
6989 return ret;
6990}
6991
6992/**
6993 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6994 * @hddctx: HDD context
6995 * @data: rssi breached event data
6996 *
6997 * This function reads the rssi breached event %data and fill in the skb with
6998 * NL attributes and send up the NL event.
6999 * This callback execute in atomic context and must not invoke any
7000 * blocking calls.
7001 *
7002 * Return: none
7003 */
7004void hdd_rssi_threshold_breached_cb(void *hddctx,
7005 struct rssi_breach_event *data)
7006{
7007 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7008 int status;
7009 struct sk_buff *skb;
7010
7011 ENTER();
7012 status = wlan_hdd_validate_context(pHddCtx);
7013
7014 if (0 != status) {
7015 return;
7016 }
7017
7018 if (!data) {
7019 hddLog(LOGE, FL("data is null"));
7020 return;
7021 }
7022
7023 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7025 NULL,
7026#endif
7027 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7028 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7029 GFP_KERNEL);
7030
7031 if (!skb) {
7032 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7033 return;
7034 }
7035
7036 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7037 data->request_id, data->curr_rssi);
7038 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7039 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7040
7041 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7042 data->request_id) ||
7043 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7044 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7045 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7046 data->curr_rssi)) {
7047 hddLog(LOGE, FL("nla put fail"));
7048 goto fail;
7049 }
7050
7051 cfg80211_vendor_event(skb, GFP_KERNEL);
7052 return;
7053
7054fail:
7055 kfree_skb(skb);
7056 return;
7057}
7058
7059
7060
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307061/**
7062 * __wlan_hdd_cfg80211_setband() - set band
7063 * @wiphy: Pointer to wireless phy
7064 * @wdev: Pointer to wireless device
7065 * @data: Pointer to data
7066 * @data_len: Data length
7067 *
7068 * Return: 0 on success, negative errno on failure
7069 */
7070static int
7071__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7072 struct wireless_dev *wdev,
7073 const void *data,
7074 int data_len)
7075{
7076 struct net_device *dev = wdev->netdev;
7077 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7078 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7079 int ret;
7080 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7081 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7082
7083 ENTER();
7084
7085 ret = wlan_hdd_validate_context(hdd_ctx);
7086 if (0 != ret) {
7087 hddLog(LOGE, FL("HDD context is not valid"));
7088 return ret;
7089 }
7090
7091 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7092 policy)) {
7093 hddLog(LOGE, FL("Invalid ATTR"));
7094 return -EINVAL;
7095 }
7096
7097 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7098 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7099 return -EINVAL;
7100 }
7101
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307102 hdd_ctx->isSetBandByNL = TRUE;
7103 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307104 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307105 hdd_ctx->isSetBandByNL = FALSE;
7106
7107 EXIT();
7108 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307109}
7110
7111/**
7112 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7113 * @wiphy: wiphy structure pointer
7114 * @wdev: Wireless device structure pointer
7115 * @data: Pointer to the data received
7116 * @data_len: Length of @data
7117 *
7118 * Return: 0 on success; errno on failure
7119 */
7120static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7121 struct wireless_dev *wdev,
7122 const void *data,
7123 int data_len)
7124{
7125 int ret = 0;
7126
7127 vos_ssr_protect(__func__);
7128 ret = __wlan_hdd_cfg80211_setband(wiphy,
7129 wdev, data, data_len);
7130 vos_ssr_unprotect(__func__);
7131
7132 return ret;
7133}
7134
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307135#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7136/**
7137 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7138 * @hdd_ctx: HDD context
7139 * @request_id: [input] request id
7140 * @pattern_id: [output] pattern id
7141 *
7142 * This function loops through request id to pattern id array
7143 * if the slot is available, store the request id and return pattern id
7144 * if entry exists, return the pattern id
7145 *
7146 * Return: 0 on success and errno on failure
7147 */
7148static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7149 uint32_t request_id,
7150 uint8_t *pattern_id)
7151{
7152 uint32_t i;
7153
7154 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7155 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7156 {
7157 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7158 {
7159 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7160 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7161 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7162 return 0;
7163 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7164 request_id) {
7165 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7166 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7167 return 0;
7168 }
7169 }
7170 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7171 return -EINVAL;
7172}
7173
7174/**
7175 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7176 * @hdd_ctx: HDD context
7177 * @request_id: [input] request id
7178 * @pattern_id: [output] pattern id
7179 *
7180 * This function loops through request id to pattern id array
7181 * reset request id to 0 (slot available again) and
7182 * return pattern id
7183 *
7184 * Return: 0 on success and errno on failure
7185 */
7186static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7187 uint32_t request_id,
7188 uint8_t *pattern_id)
7189{
7190 uint32_t i;
7191
7192 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7193 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7194 {
7195 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7196 {
7197 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7198 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7199 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7200 return 0;
7201 }
7202 }
7203 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7204 return -EINVAL;
7205}
7206
7207
7208/*
7209 * define short names for the global vendor params
7210 * used by __wlan_hdd_cfg80211_offloaded_packets()
7211 */
7212#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7213#define PARAM_REQUEST_ID \
7214 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7215#define PARAM_CONTROL \
7216 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7217#define PARAM_IP_PACKET \
7218 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7219#define PARAM_SRC_MAC_ADDR \
7220 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7221#define PARAM_DST_MAC_ADDR \
7222 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7223#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7224
7225/**
7226 * wlan_hdd_add_tx_ptrn() - add tx pattern
7227 * @adapter: adapter pointer
7228 * @hdd_ctx: hdd context
7229 * @tb: nl attributes
7230 *
7231 * This function reads the NL attributes and forms a AddTxPtrn message
7232 * posts it to SME.
7233 *
7234 */
7235static int
7236wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7237 struct nlattr **tb)
7238{
7239 struct sSirAddPeriodicTxPtrn *add_req;
7240 eHalStatus status;
7241 uint32_t request_id, ret, len;
7242 uint8_t pattern_id = 0;
7243 v_MACADDR_t dst_addr;
7244 uint16_t eth_type = htons(ETH_P_IP);
7245
7246 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7247 {
7248 hddLog(LOGE, FL("Not in Connected state!"));
7249 return -ENOTSUPP;
7250 }
7251
7252 add_req = vos_mem_malloc(sizeof(*add_req));
7253 if (!add_req)
7254 {
7255 hddLog(LOGE, FL("memory allocation failed"));
7256 return -ENOMEM;
7257 }
7258
7259 /* Parse and fetch request Id */
7260 if (!tb[PARAM_REQUEST_ID])
7261 {
7262 hddLog(LOGE, FL("attr request id failed"));
7263 goto fail;
7264 }
7265
7266 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7267 hddLog(LOG1, FL("Request Id: %u"), request_id);
7268 if (request_id == 0)
7269 {
7270 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307271 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307272 }
7273
7274 if (!tb[PARAM_PERIOD])
7275 {
7276 hddLog(LOGE, FL("attr period failed"));
7277 goto fail;
7278 }
7279 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7280 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7281 if (add_req->usPtrnIntervalMs == 0)
7282 {
7283 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7284 goto fail;
7285 }
7286
7287 if (!tb[PARAM_SRC_MAC_ADDR])
7288 {
7289 hddLog(LOGE, FL("attr source mac address failed"));
7290 goto fail;
7291 }
7292 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7293 VOS_MAC_ADDR_SIZE);
7294 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7295 MAC_ADDR_ARRAY(add_req->macAddress));
7296
7297 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7298 VOS_MAC_ADDR_SIZE))
7299 {
7300 hddLog(LOGE,
7301 FL("input src mac address and connected ap bssid are different"));
7302 goto fail;
7303 }
7304
7305 if (!tb[PARAM_DST_MAC_ADDR])
7306 {
7307 hddLog(LOGE, FL("attr dst mac address failed"));
7308 goto fail;
7309 }
7310 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7311 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7312 MAC_ADDR_ARRAY(dst_addr.bytes));
7313
7314 if (!tb[PARAM_IP_PACKET])
7315 {
7316 hddLog(LOGE, FL("attr ip packet failed"));
7317 goto fail;
7318 }
7319 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7320 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7321
7322 if (add_req->ucPtrnSize < 0 ||
7323 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7324 HDD_ETH_HEADER_LEN))
7325 {
7326 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7327 add_req->ucPtrnSize);
7328 goto fail;
7329 }
7330
7331 len = 0;
7332 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7333 len += VOS_MAC_ADDR_SIZE;
7334 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7335 VOS_MAC_ADDR_SIZE);
7336 len += VOS_MAC_ADDR_SIZE;
7337 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7338 len += 2;
7339
7340 /*
7341 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7342 * ------------------------------------------------------------
7343 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7344 * ------------------------------------------------------------
7345 */
7346 vos_mem_copy(&add_req->ucPattern[len],
7347 nla_data(tb[PARAM_IP_PACKET]),
7348 add_req->ucPtrnSize);
7349 add_req->ucPtrnSize += len;
7350
7351 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7352 add_req->ucPattern, add_req->ucPtrnSize);
7353
7354 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7355 if (ret)
7356 {
7357 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7358 goto fail;
7359 }
7360 add_req->ucPtrnId = pattern_id;
7361 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7362
7363 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7364 if (!HAL_STATUS_SUCCESS(status))
7365 {
7366 hddLog(LOGE,
7367 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7368 goto fail;
7369 }
7370
7371 EXIT();
7372 vos_mem_free(add_req);
7373 return 0;
7374
7375fail:
7376 vos_mem_free(add_req);
7377 return -EINVAL;
7378}
7379
7380/**
7381 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7382 * @adapter: adapter pointer
7383 * @hdd_ctx: hdd context
7384 * @tb: nl attributes
7385 *
7386 * This function reads the NL attributes and forms a DelTxPtrn message
7387 * posts it to SME.
7388 *
7389 */
7390static int
7391wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7392 struct nlattr **tb)
7393{
7394 struct sSirDelPeriodicTxPtrn *del_req;
7395 eHalStatus status;
7396 uint32_t request_id, ret;
7397 uint8_t pattern_id = 0;
7398
7399 /* Parse and fetch request Id */
7400 if (!tb[PARAM_REQUEST_ID])
7401 {
7402 hddLog(LOGE, FL("attr request id failed"));
7403 return -EINVAL;
7404 }
7405 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7406 if (request_id == 0)
7407 {
7408 hddLog(LOGE, FL("request_id cannot be zero"));
7409 return -EINVAL;
7410 }
7411
7412 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7413 if (ret)
7414 {
7415 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7416 return -EINVAL;
7417 }
7418
7419 del_req = vos_mem_malloc(sizeof(*del_req));
7420 if (!del_req)
7421 {
7422 hddLog(LOGE, FL("memory allocation failed"));
7423 return -ENOMEM;
7424 }
7425
7426 vos_mem_set(del_req, sizeof(*del_req), 0);
7427 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7428 VOS_MAC_ADDR_SIZE);
7429 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7430 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7431 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7432 request_id, pattern_id, del_req->ucPatternIdBitmap);
7433
7434 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7435 if (!HAL_STATUS_SUCCESS(status))
7436 {
7437 hddLog(LOGE,
7438 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7439 goto fail;
7440 }
7441
7442 EXIT();
7443 vos_mem_free(del_req);
7444 return 0;
7445
7446fail:
7447 vos_mem_free(del_req);
7448 return -EINVAL;
7449}
7450
7451
7452/**
7453 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7454 * @wiphy: Pointer to wireless phy
7455 * @wdev: Pointer to wireless device
7456 * @data: Pointer to data
7457 * @data_len: Data length
7458 *
7459 * Return: 0 on success, negative errno on failure
7460 */
7461static int
7462__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7463 struct wireless_dev *wdev,
7464 const void *data,
7465 int data_len)
7466{
7467 struct net_device *dev = wdev->netdev;
7468 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7469 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7470 struct nlattr *tb[PARAM_MAX + 1];
7471 uint8_t control;
7472 int ret;
7473 static const struct nla_policy policy[PARAM_MAX + 1] =
7474 {
7475 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7476 [PARAM_CONTROL] = { .type = NLA_U32 },
7477 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7478 .len = VOS_MAC_ADDR_SIZE },
7479 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7480 .len = VOS_MAC_ADDR_SIZE },
7481 [PARAM_PERIOD] = { .type = NLA_U32 },
7482 };
7483
7484 ENTER();
7485
7486 ret = wlan_hdd_validate_context(hdd_ctx);
7487 if (0 != ret)
7488 {
7489 hddLog(LOGE, FL("HDD context is not valid"));
7490 return ret;
7491 }
7492
7493 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7494 {
7495 hddLog(LOGE,
7496 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7497 return -ENOTSUPP;
7498 }
7499
7500 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7501 {
7502 hddLog(LOGE, FL("Invalid ATTR"));
7503 return -EINVAL;
7504 }
7505
7506 if (!tb[PARAM_CONTROL])
7507 {
7508 hddLog(LOGE, FL("attr control failed"));
7509 return -EINVAL;
7510 }
7511 control = nla_get_u32(tb[PARAM_CONTROL]);
7512 hddLog(LOG1, FL("Control: %d"), control);
7513
7514 if (control == WLAN_START_OFFLOADED_PACKETS)
7515 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7516 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7517 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7518 else
7519 {
7520 hddLog(LOGE, FL("Invalid control: %d"), control);
7521 return -EINVAL;
7522 }
7523}
7524
7525/*
7526 * done with short names for the global vendor params
7527 * used by __wlan_hdd_cfg80211_offloaded_packets()
7528 */
7529#undef PARAM_MAX
7530#undef PARAM_REQUEST_ID
7531#undef PARAM_CONTROL
7532#undef PARAM_IP_PACKET
7533#undef PARAM_SRC_MAC_ADDR
7534#undef PARAM_DST_MAC_ADDR
7535#undef PARAM_PERIOD
7536
7537/**
7538 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7539 * @wiphy: wiphy structure pointer
7540 * @wdev: Wireless device structure pointer
7541 * @data: Pointer to the data received
7542 * @data_len: Length of @data
7543 *
7544 * Return: 0 on success; errno on failure
7545 */
7546static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7547 struct wireless_dev *wdev,
7548 const void *data,
7549 int data_len)
7550{
7551 int ret = 0;
7552
7553 vos_ssr_protect(__func__);
7554 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7555 wdev, data, data_len);
7556 vos_ssr_unprotect(__func__);
7557
7558 return ret;
7559}
7560#endif
7561
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307562static const struct
7563nla_policy
7564qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307565 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7566 .type = NLA_BINARY,
7567 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307568};
7569
7570/**
7571 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7572 * get link properties like nss, rate flags and operating frequency for
7573 * the connection with the given peer.
7574 * @wiphy: WIPHY structure pointer
7575 * @wdev: Wireless device structure pointer
7576 * @data: Pointer to the data received
7577 * @data_len: Length of the data received
7578 *
7579 * This function return the above link properties on success.
7580 *
7581 * Return: 0 on success and errno on failure
7582 */
7583static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7584 struct wireless_dev *wdev,
7585 const void *data,
7586 int data_len)
7587{
7588 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7589 struct net_device *dev = wdev->netdev;
7590 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7591 hdd_station_ctx_t *hdd_sta_ctx;
7592 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7593 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7594 uint32_t sta_id;
7595 struct sk_buff *reply_skb;
7596 uint32_t rate_flags = 0;
7597 uint8_t nss;
7598 uint8_t final_rate_flags = 0;
7599 uint32_t freq;
7600 v_CONTEXT_t pVosContext = NULL;
7601 ptSapContext pSapCtx = NULL;
7602
7603 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7605 return -EINVAL;
7606 }
7607
7608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7609 qca_wlan_vendor_attr_policy)) {
7610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7611 return -EINVAL;
7612 }
7613
7614 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7615 hddLog(VOS_TRACE_LEVEL_ERROR,
7616 FL("Attribute peerMac not provided for mode=%d"),
7617 adapter->device_mode);
7618 return -EINVAL;
7619 }
7620
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307621 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7622 hddLog(VOS_TRACE_LEVEL_ERROR,
7623 FL("Attribute peerMac is invalid=%d"),
7624 adapter->device_mode);
7625 return -EINVAL;
7626 }
7627
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307628 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7629 sizeof(peer_mac));
7630 hddLog(VOS_TRACE_LEVEL_INFO,
7631 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7632 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7633
7634 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7635 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7636 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7637 if ((hdd_sta_ctx->conn_info.connState !=
7638 eConnectionState_Associated) ||
7639 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7640 VOS_MAC_ADDRESS_LEN)) {
7641 hddLog(VOS_TRACE_LEVEL_ERROR,
7642 FL("Not Associated to mac "MAC_ADDRESS_STR),
7643 MAC_ADDR_ARRAY(peer_mac));
7644 return -EINVAL;
7645 }
7646
7647 nss = 1; //pronto supports only one spatial stream
7648 freq = vos_chan_to_freq(
7649 hdd_sta_ctx->conn_info.operationChannel);
7650 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7651
7652 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7653 adapter->device_mode == WLAN_HDD_SOFTAP) {
7654
7655 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7656 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7657 if(pSapCtx == NULL){
7658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7659 FL("psapCtx is NULL"));
7660 return -ENOENT;
7661 }
7662
7663
7664 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7665 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7666 !vos_is_macaddr_broadcast(
7667 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7668 vos_mem_compare(
7669 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7670 peer_mac, VOS_MAC_ADDRESS_LEN))
7671 break;
7672 }
7673
7674 if (WLAN_MAX_STA_COUNT == sta_id) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("No active peer with mac="MAC_ADDRESS_STR),
7677 MAC_ADDR_ARRAY(peer_mac));
7678 return -EINVAL;
7679 }
7680
7681 nss = 1; //pronto supports only one spatial stream
7682 freq = vos_chan_to_freq(
7683 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7684 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7685 } else {
7686 hddLog(VOS_TRACE_LEVEL_ERROR,
7687 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7688 MAC_ADDR_ARRAY(peer_mac));
7689 return -EINVAL;
7690 }
7691
7692 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7693 if (rate_flags & eHAL_TX_RATE_VHT80) {
7694 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307695#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7696 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307697 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307698#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307699 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7700 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307701#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7702 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307703 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307704#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307705 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7706 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7707 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7708 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307709#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7710 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307711 if (rate_flags & eHAL_TX_RATE_HT40)
7712 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307713#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307714 }
7715
7716 if (rate_flags & eHAL_TX_RATE_SGI) {
7717 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7718 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7719 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7720 }
7721 }
7722
7723 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7724 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7725
7726 if (NULL == reply_skb) {
7727 hddLog(VOS_TRACE_LEVEL_ERROR,
7728 FL("getLinkProperties: skb alloc failed"));
7729 return -EINVAL;
7730 }
7731
7732 if (nla_put_u8(reply_skb,
7733 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7734 nss) ||
7735 nla_put_u8(reply_skb,
7736 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7737 final_rate_flags) ||
7738 nla_put_u32(reply_skb,
7739 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7740 freq)) {
7741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7742 kfree_skb(reply_skb);
7743 return -EINVAL;
7744 }
7745
7746 return cfg80211_vendor_cmd_reply(reply_skb);
7747}
7748
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307749#define BEACON_MISS_THRESH_2_4 \
7750 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7751#define BEACON_MISS_THRESH_5_0 \
7752 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307753#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7754#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7755#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7756#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307757#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7758 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307759#define PARAM_FORCE_RSN_IE \
7760 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307761/*
7762 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7763 * @hdd_ctx: hdd context
7764 * @enable: Value received in the command, 1 for disable and 2 for enable
7765 *
7766 * Return: void
7767 */
7768static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7769{
7770 if (!hdd_ctx) {
7771 hddLog(LOGE, "hdd_ctx NULL");
7772 return;
7773 }
7774
7775 sme_set_qpower(hdd_ctx->hHal, enable);
7776}
7777
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307778/**
7779 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7780 * vendor command
7781 *
7782 * @wiphy: wiphy device pointer
7783 * @wdev: wireless device pointer
7784 * @data: Vendor command data buffer
7785 * @data_len: Buffer length
7786 *
7787 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7788 *
7789 * Return: EOK or other error codes.
7790 */
7791
7792static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7793 struct wireless_dev *wdev,
7794 const void *data,
7795 int data_len)
7796{
7797 struct net_device *dev = wdev->netdev;
7798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7799 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7800 hdd_station_ctx_t *pHddStaCtx;
7801 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7802 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307803 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307804 eHalStatus status;
7805 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307806 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307807 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307808
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307809 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7810 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7811 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307812 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7813 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7814 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307815 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7816 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307817 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307818 };
7819
7820 ENTER();
7821
7822 if (VOS_FTM_MODE == hdd_get_conparam()) {
7823 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7824 return -EINVAL;
7825 }
7826
7827 ret_val = wlan_hdd_validate_context(pHddCtx);
7828 if (ret_val) {
7829 return ret_val;
7830 }
7831
7832 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7833
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307834 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7835 hddLog(LOGE, FL("Invalid ATTR"));
7836 return -EINVAL;
7837 }
7838
7839 /* check the Wifi Capability */
7840 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7841 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7842 {
7843 hddLog(VOS_TRACE_LEVEL_ERROR,
7844 FL("WIFICONFIG not supported by Firmware"));
7845 return -EINVAL;
7846 }
7847
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307848 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7849 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7850 modifyRoamParamsReq.value =
7851 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7852
7853 if (eHAL_STATUS_SUCCESS !=
7854 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7855 {
7856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7857 ret_val = -EINVAL;
7858 }
7859 return ret_val;
7860 }
7861
7862 /* Moved this down in order to provide provision to set beacon
7863 * miss penalty count irrespective of connection state.
7864 */
7865 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7866 hddLog(LOGE, FL("Not in Connected state!"));
7867 return -ENOTSUPP;
7868 }
7869
7870 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307871
7872 if (!pReq) {
7873 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7874 "%s: Not able to allocate memory for tSetWifiConfigParams",
7875 __func__);
7876 return eHAL_STATUS_E_MALLOC_FAILED;
7877 }
7878
7879 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7880
7881 pReq->sessionId = pAdapter->sessionId;
7882 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7883
7884 if (tb[PARAM_MODULATED_DTIM]) {
7885 pReq->paramValue = nla_get_u32(
7886 tb[PARAM_MODULATED_DTIM]);
7887 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7888 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307889 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307890 hdd_set_pwrparams(pHddCtx);
7891 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7892 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7893
7894 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7895 iw_full_power_cbfn, pAdapter,
7896 eSME_FULL_PWR_NEEDED_BY_HDD);
7897 }
7898 else
7899 {
7900 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7901 }
7902 }
7903
7904 if (tb[PARAM_STATS_AVG_FACTOR]) {
7905 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7906 pReq->paramValue = nla_get_u16(
7907 tb[PARAM_STATS_AVG_FACTOR]);
7908 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7909 pReq->paramType, pReq->paramValue);
7910 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7911
7912 if (eHAL_STATUS_SUCCESS != status)
7913 {
7914 vos_mem_free(pReq);
7915 pReq = NULL;
7916 ret_val = -EPERM;
7917 return ret_val;
7918 }
7919 }
7920
7921
7922 if (tb[PARAM_GUARD_TIME]) {
7923 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7924 pReq->paramValue = nla_get_u32(
7925 tb[PARAM_GUARD_TIME]);
7926 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7927 pReq->paramType, pReq->paramValue);
7928 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7929
7930 if (eHAL_STATUS_SUCCESS != status)
7931 {
7932 vos_mem_free(pReq);
7933 pReq = NULL;
7934 ret_val = -EPERM;
7935 return ret_val;
7936 }
7937
7938 }
7939
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307940 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7941 hb_thresh_val = nla_get_u8(
7942 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7943
7944 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7945 hb_thresh_val);
7946 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7947 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7948 NULL, eANI_BOOLEAN_FALSE);
7949
7950 status = sme_update_hb_threshold(
7951 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7952 WNI_CFG_HEART_BEAT_THRESHOLD,
7953 hb_thresh_val, eCSR_BAND_24);
7954 if (eHAL_STATUS_SUCCESS != status) {
7955 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7956 vos_mem_free(pReq);
7957 pReq = NULL;
7958 return -EPERM;
7959 }
7960 }
7961
7962 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7963 hb_thresh_val = nla_get_u8(
7964 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7965
7966 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7967 hb_thresh_val);
7968 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7969 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7970 NULL, eANI_BOOLEAN_FALSE);
7971
7972 status = sme_update_hb_threshold(
7973 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7974 WNI_CFG_HEART_BEAT_THRESHOLD,
7975 hb_thresh_val, eCSR_BAND_5G);
7976 if (eHAL_STATUS_SUCCESS != status) {
7977 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7978 vos_mem_free(pReq);
7979 pReq = NULL;
7980 return -EPERM;
7981 }
7982 }
7983
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307984 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
7985 qpower = nla_get_u8(
7986 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
7987
7988 if(qpower > 1) {
7989 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
7990 vos_mem_free(pReq);
7991 pReq = NULL;
7992 return -EINVAL;
7993 }
7994 /* FW is expacting qpower as 1 for Disable and 2 for enable */
7995 qpower++;
7996 hdd_set_qpower(pHddCtx, qpower);
7997 }
7998
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307999 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8000 pHddCtx->cfg_ini->force_rsne_override) {
8001 uint8_t force_rsne_override;
8002
8003 force_rsne_override =
8004 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8005 if (force_rsne_override > 1) {
8006 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8007 ret_val = -EINVAL;
8008 }
8009 pHddCtx->force_rsne_override = force_rsne_override;
8010 hddLog(LOG1, "force_rsne_override - %d",
8011 pHddCtx->force_rsne_override);
8012 }
8013
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308014 EXIT();
8015 return ret_val;
8016}
8017
8018/**
8019 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8020 * vendor command
8021 *
8022 * @wiphy: wiphy device pointer
8023 * @wdev: wireless device pointer
8024 * @data: Vendor command data buffer
8025 * @data_len: Buffer length
8026 *
8027 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8028 *
8029 * Return: EOK or other error codes.
8030 */
8031static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8032 struct wireless_dev *wdev,
8033 const void *data,
8034 int data_len)
8035{
8036 int ret;
8037
8038 vos_ssr_protect(__func__);
8039 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8040 data, data_len);
8041 vos_ssr_unprotect(__func__);
8042
8043 return ret;
8044}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308045
8046/*
8047 * define short names for the global vendor params
8048 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8049 */
8050#define STATS_SET_INVALID \
8051 QCA_ATTR_NUD_STATS_SET_INVALID
8052#define STATS_SET_START \
8053 QCA_ATTR_NUD_STATS_SET_START
8054#define STATS_GW_IPV4 \
8055 QCA_ATTR_NUD_STATS_GW_IPV4
8056#define STATS_SET_MAX \
8057 QCA_ATTR_NUD_STATS_SET_MAX
8058
8059const struct nla_policy
8060qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8061{
8062 [STATS_SET_START] = {.type = NLA_FLAG },
8063 [STATS_GW_IPV4] = {.type = NLA_U32 },
8064};
8065
8066/**
8067 * hdd_set_nud_stats_cb() - hdd callback api to get status
8068 * @data: pointer to adapter
8069 * @rsp: status
8070 *
8071 * Return: None
8072 */
8073static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8074{
8075
8076 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8077
8078 if (NULL == adapter)
8079 return;
8080
8081 if (VOS_STATUS_SUCCESS == rsp) {
8082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8083 "%s success received STATS_SET_START", __func__);
8084 } else {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8086 "%s STATS_SET_START Failed!!", __func__);
8087 }
8088 return;
8089}
8090
8091/**
8092 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8093 * @wiphy: pointer to wireless wiphy structure.
8094 * @wdev: pointer to wireless_dev structure.
8095 * @data: pointer to apfind configuration data.
8096 * @data_len: the length in byte of apfind data.
8097 *
8098 * This is called when wlan driver needs to send arp stats to
8099 * firmware.
8100 *
8101 * Return: An error code or 0 on success.
8102 */
8103static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8104 struct wireless_dev *wdev,
8105 const void *data, int data_len)
8106{
8107 struct nlattr *tb[STATS_SET_MAX + 1];
8108 struct net_device *dev = wdev->netdev;
8109 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8110 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308111 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308112 setArpStatsParams arp_stats_params;
8113 int err = 0;
8114
8115 ENTER();
8116
8117 err = wlan_hdd_validate_context(hdd_ctx);
8118 if (0 != err)
8119 return err;
8120
8121 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8123 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8124 return -EINVAL;
8125 }
8126
8127 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8128 qca_wlan_vendor_set_nud_stats);
8129 if (err)
8130 {
8131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8132 "%s STATS_SET_START ATTR", __func__);
8133 return err;
8134 }
8135
8136 if (tb[STATS_SET_START])
8137 {
8138 if (!tb[STATS_GW_IPV4]) {
8139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8140 "%s STATS_SET_START CMD", __func__);
8141 return -EINVAL;
8142 }
8143 arp_stats_params.flag = true;
8144 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8145 } else {
8146 arp_stats_params.flag = false;
8147 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308148 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8150 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8152 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308153
8154 arp_stats_params.pkt_type = 1; // ARP packet type
8155
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308156 if (arp_stats_params.flag) {
8157 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8158 WLANTL_SetARPFWDatapath(pVosContext, true);
8159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8160 "%s Set FW in data path for ARP with tgt IP :%d",
8161 __func__, hdd_ctx->track_arp_ip);
8162 }
8163 else {
8164 WLANTL_SetARPFWDatapath(pVosContext, false);
8165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8166 "%s Remove FW from data path", __func__);
8167 }
8168
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308169 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8170 arp_stats_params.data_ctx = adapter;
8171
8172 if (eHAL_STATUS_SUCCESS !=
8173 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8175 "%s STATS_SET_START CMD Failed!!", __func__);
8176 return -EINVAL;
8177 }
8178
8179 EXIT();
8180
8181 return err;
8182}
8183
8184/**
8185 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8186 * @wiphy: pointer to wireless wiphy structure.
8187 * @wdev: pointer to wireless_dev structure.
8188 * @data: pointer to apfind configuration data.
8189 * @data_len: the length in byte of apfind data.
8190 *
8191 * This is called when wlan driver needs to send arp stats to
8192 * firmware.
8193 *
8194 * Return: An error code or 0 on success.
8195 */
8196static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8197 struct wireless_dev *wdev,
8198 const void *data, int data_len)
8199{
8200 int ret;
8201
8202 vos_ssr_protect(__func__);
8203 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8204 vos_ssr_unprotect(__func__);
8205
8206 return ret;
8207}
8208#undef STATS_SET_INVALID
8209#undef STATS_SET_START
8210#undef STATS_GW_IPV4
8211#undef STATS_SET_MAX
8212
8213/*
8214 * define short names for the global vendor params
8215 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8216 */
8217#define STATS_GET_INVALID \
8218 QCA_ATTR_NUD_STATS_SET_INVALID
8219#define COUNT_FROM_NETDEV \
8220 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8221#define COUNT_TO_LOWER_MAC \
8222 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8223#define RX_COUNT_BY_LOWER_MAC \
8224 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8225#define COUNT_TX_SUCCESS \
8226 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8227#define RSP_RX_COUNT_BY_LOWER_MAC \
8228 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8229#define RSP_RX_COUNT_BY_UPPER_MAC \
8230 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8231#define RSP_COUNT_TO_NETDEV \
8232 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8233#define RSP_COUNT_OUT_OF_ORDER_DROP \
8234 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8235#define AP_LINK_ACTIVE \
8236 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8237#define AP_LINK_DAD \
8238 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8239#define STATS_GET_MAX \
8240 QCA_ATTR_NUD_STATS_GET_MAX
8241
8242const struct nla_policy
8243qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8244{
8245 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8246 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8247 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8248 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8249 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8250 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8251 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8252 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8253 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8254 [AP_LINK_DAD] = {.type = NLA_FLAG },
8255};
8256
8257static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8258{
8259
8260 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308261 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308262 struct hdd_nud_stats_context *context;
8263 int status;
8264
8265 ENTER();
8266
8267 if (NULL == adapter)
8268 return;
8269
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308270 if (!rsp) {
8271 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308272 return;
8273 }
8274
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308275 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8276 status = wlan_hdd_validate_context(hdd_ctx);
8277 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308278 return;
8279 }
8280
8281 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8282 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8283 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8284 adapter->dad |= rsp->dad;
8285
8286 spin_lock(&hdd_context_lock);
8287 context = &hdd_ctx->nud_stats_context;
8288 complete(&context->response_event);
8289 spin_unlock(&hdd_context_lock);
8290
8291 return;
8292}
8293static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8294 struct wireless_dev *wdev,
8295 const void *data, int data_len)
8296{
8297 int err = 0;
8298 unsigned long rc;
8299 struct hdd_nud_stats_context *context;
8300 struct net_device *dev = wdev->netdev;
8301 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8302 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8303 getArpStatsParams arp_stats_params;
8304 struct sk_buff *skb;
8305
8306 ENTER();
8307
8308 err = wlan_hdd_validate_context(hdd_ctx);
8309 if (0 != err)
8310 return err;
8311
8312 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8313 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8314 arp_stats_params.data_ctx = adapter;
8315
8316 spin_lock(&hdd_context_lock);
8317 context = &hdd_ctx->nud_stats_context;
8318 INIT_COMPLETION(context->response_event);
8319 spin_unlock(&hdd_context_lock);
8320
8321 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8323 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8324 return -EINVAL;
8325 }
8326
8327 if (eHAL_STATUS_SUCCESS !=
8328 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8330 "%s STATS_SET_START CMD Failed!!", __func__);
8331 return -EINVAL;
8332 }
8333
8334 rc = wait_for_completion_timeout(&context->response_event,
8335 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8336 if (!rc)
8337 {
8338 hddLog(LOGE,
8339 FL("Target response timed out request "));
8340 return -ETIMEDOUT;
8341 }
8342
8343 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8344 WLAN_NUD_STATS_LEN);
8345 if (!skb)
8346 {
8347 hddLog(VOS_TRACE_LEVEL_ERROR,
8348 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8349 __func__);
8350 return -ENOMEM;
8351 }
8352
8353 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8354 adapter->hdd_stats.hddArpStats.txCount) ||
8355 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8356 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8357 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8358 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8359 nla_put_u16(skb, COUNT_TX_SUCCESS,
8360 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8361 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8362 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8363 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8364 adapter->hdd_stats.hddArpStats.rxCount) ||
8365 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8366 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8367 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8368 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8369 hddLog(LOGE, FL("nla put fail"));
8370 kfree_skb(skb);
8371 return -EINVAL;
8372 }
8373 if (adapter->con_status)
8374 nla_put_flag(skb, AP_LINK_ACTIVE);
8375 if (adapter->dad)
8376 nla_put_flag(skb, AP_LINK_DAD);
8377
8378 cfg80211_vendor_cmd_reply(skb);
8379 return err;
8380}
8381
8382static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8383 struct wireless_dev *wdev,
8384 const void *data, int data_len)
8385{
8386 int ret;
8387
8388 vos_ssr_protect(__func__);
8389 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8390 vos_ssr_unprotect(__func__);
8391
8392 return ret;
8393}
8394
8395#undef QCA_ATTR_NUD_STATS_SET_INVALID
8396#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8397#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8398#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8400#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8404#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8405#undef QCA_ATTR_NUD_STATS_GET_MAX
8406
8407
8408
Kapil Guptaee33bf12016-12-20 18:27:37 +05308409#ifdef WLAN_FEATURE_APFIND
8410/**
8411 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8412 * @wiphy: pointer to wireless wiphy structure.
8413 * @wdev: pointer to wireless_dev structure.
8414 * @data: pointer to apfind configuration data.
8415 * @data_len: the length in byte of apfind data.
8416 *
8417 * This is called when wlan driver needs to send APFIND configurations to
8418 * firmware.
8419 *
8420 * Return: An error code or 0 on success.
8421 */
8422static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8423 struct wireless_dev *wdev,
8424 const void *data, int data_len)
8425{
8426 struct sme_ap_find_request_req apfind_req;
8427 VOS_STATUS status;
8428 int ret_val;
8429 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8430
8431 ENTER();
8432
8433 ret_val = wlan_hdd_validate_context(hdd_ctx);
8434 if (ret_val)
8435 return ret_val;
8436
8437 if (VOS_FTM_MODE == hdd_get_conparam()) {
8438 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8439 return -EPERM;
8440 }
8441
8442 apfind_req.request_data_len = data_len;
8443 apfind_req.request_data = data;
8444
8445 status = sme_apfind_set_cmd(&apfind_req);
8446 if (VOS_STATUS_SUCCESS != status) {
8447 ret_val = -EIO;
8448 }
8449 return ret_val;
8450}
8451
8452/**
8453 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8454 * @wiphy: pointer to wireless wiphy structure.
8455 * @wdev: pointer to wireless_dev structure.
8456 * @data: pointer to apfind configuration data.
8457 * @data_len: the length in byte of apfind data.
8458 *
8459 * This is called when wlan driver needs to send APFIND configurations to
8460 * firmware.
8461 *
8462 * Return: An error code or 0 on success.
8463 */
8464static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8465 struct wireless_dev *wdev,
8466 const void *data, int data_len)
8467{
8468 int ret;
8469
8470 vos_ssr_protect(__func__);
8471 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8472 vos_ssr_unprotect(__func__);
8473
8474 return ret;
8475}
8476#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308477
8478/**
8479 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8480 * @wiphy: pointer to wireless wiphy structure.
8481 * @wdev: pointer to wireless_dev structure.
8482 * @data: Pointer to the data to be passed via vendor interface
8483 * @data_len:Length of the data to be passed
8484 *
8485 * This is called by userspace to know the supported logger features
8486 *
8487 * Return: Return the Success or Failure code.
8488 */
8489static int
8490__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8491 struct wireless_dev *wdev,
8492 const void *data, int data_len)
8493{
8494 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8495 int status;
8496 uint32_t features;
8497 struct sk_buff *reply_skb = NULL;
8498
8499 if (VOS_FTM_MODE == hdd_get_conparam()) {
8500 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8501 return -EINVAL;
8502 }
8503
8504 status = wlan_hdd_validate_context(hdd_ctx);
8505 if (0 != status)
8506 return -EINVAL;
8507
8508 features = 0;
8509
8510 if (hdd_is_memdump_supported())
8511 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8512
8513 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8514 hdd_ctx->cfg_ini->enableFatalEvent &&
8515 hdd_ctx->is_fatal_event_log_sup) {
8516 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8517 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8518 }
8519
8520 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8521 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8522 if (!reply_skb) {
8523 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8524 return -ENOMEM;
8525 }
8526
8527 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8528 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8529 features)) {
8530 hddLog(LOGE, FL("nla put fail"));
8531 kfree_skb(reply_skb);
8532 return -EINVAL;
8533 }
8534
8535 return cfg80211_vendor_cmd_reply(reply_skb);
8536}
8537
8538/**
8539 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8540 * @wiphy: pointer to wireless wiphy structure.
8541 * @wdev: pointer to wireless_dev structure.
8542 * @data: Pointer to the data to be passed via vendor interface
8543 * @data_len:Length of the data to be passed
8544 *
8545 * This is called by userspace to know the supported logger features
8546 *
8547 * Return: Return the Success or Failure code.
8548 */
8549static int
8550wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8551 struct wireless_dev *wdev,
8552 const void *data, int data_len)
8553{
8554 int ret;
8555
8556 vos_ssr_protect(__func__);
8557 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8558 data, data_len);
8559 vos_ssr_unprotect(__func__);
8560
8561 return ret;
8562}
8563
Sunil Duttc69bccb2014-05-26 21:30:20 +05308564const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8565{
Mukul Sharma2a271632014-10-13 14:59:01 +05308566 {
8567 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8568 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8569 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8570 WIPHY_VENDOR_CMD_NEED_NETDEV |
8571 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308572 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308573 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308574
8575 {
8576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8579 WIPHY_VENDOR_CMD_NEED_NETDEV |
8580 WIPHY_VENDOR_CMD_NEED_RUNNING,
8581 .doit = wlan_hdd_cfg80211_nan_request
8582 },
8583
Sunil Duttc69bccb2014-05-26 21:30:20 +05308584#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8585 {
8586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8589 WIPHY_VENDOR_CMD_NEED_NETDEV |
8590 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308591 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308592 },
8593
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308601 },
8602
8603 {
8604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8607 WIPHY_VENDOR_CMD_NEED_NETDEV |
8608 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308609 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308610 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308611#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308612#ifdef WLAN_FEATURE_EXTSCAN
8613 {
8614 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8615 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8616 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8617 WIPHY_VENDOR_CMD_NEED_NETDEV |
8618 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308619 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308620 },
8621 {
8622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8625 WIPHY_VENDOR_CMD_NEED_NETDEV |
8626 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308627 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308628 },
8629 {
8630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8633 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308634 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308635 },
8636 {
8637 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8638 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8639 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8640 WIPHY_VENDOR_CMD_NEED_NETDEV |
8641 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308642 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308643 },
8644 {
8645 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8646 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8647 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8648 WIPHY_VENDOR_CMD_NEED_NETDEV |
8649 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308650 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308651 },
8652 {
8653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8655 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8656 WIPHY_VENDOR_CMD_NEED_NETDEV |
8657 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308658 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308659 },
8660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV |
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308666 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308667 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308668#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308669/*EXT TDLS*/
8670 {
8671 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8672 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8673 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8674 WIPHY_VENDOR_CMD_NEED_NETDEV |
8675 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308676 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308677 },
8678 {
8679 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8680 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8681 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8682 WIPHY_VENDOR_CMD_NEED_NETDEV |
8683 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308684 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308685 },
8686 {
8687 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8688 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8689 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8690 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308691 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308692 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308693 {
8694 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8695 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8696 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8697 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308698 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308699 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308700 {
8701 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8702 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8703 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8704 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308705 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308706 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308707 {
8708 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8709 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8710 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8711 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308712 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308713 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308714 {
8715 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8716 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8717 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8718 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308719 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308720 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308721 {
8722 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308723 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8724 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8725 WIPHY_VENDOR_CMD_NEED_NETDEV |
8726 WIPHY_VENDOR_CMD_NEED_RUNNING,
8727 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8728 },
8729 {
8730 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308731 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8732 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8733 WIPHY_VENDOR_CMD_NEED_NETDEV |
8734 WIPHY_VENDOR_CMD_NEED_RUNNING,
8735 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308736 },
8737 {
8738 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8739 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8740 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8741 WIPHY_VENDOR_CMD_NEED_NETDEV,
8742 .doit = wlan_hdd_cfg80211_wifi_logger_start
8743 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308744 {
8745 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8746 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8747 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8748 WIPHY_VENDOR_CMD_NEED_NETDEV|
8749 WIPHY_VENDOR_CMD_NEED_RUNNING,
8750 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308751 },
8752 {
8753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8756 WIPHY_VENDOR_CMD_NEED_NETDEV |
8757 WIPHY_VENDOR_CMD_NEED_RUNNING,
8758 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308759 },
8760 {
8761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8764 WIPHY_VENDOR_CMD_NEED_NETDEV |
8765 WIPHY_VENDOR_CMD_NEED_RUNNING,
8766 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308767 },
8768#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8769 {
8770 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8771 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8772 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8773 WIPHY_VENDOR_CMD_NEED_NETDEV |
8774 WIPHY_VENDOR_CMD_NEED_RUNNING,
8775 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308776 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308777#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308778 {
8779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8782 WIPHY_VENDOR_CMD_NEED_NETDEV |
8783 WIPHY_VENDOR_CMD_NEED_RUNNING,
8784 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308785 },
8786 {
8787 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8788 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8789 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8790 WIPHY_VENDOR_CMD_NEED_NETDEV |
8791 WIPHY_VENDOR_CMD_NEED_RUNNING,
8792 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308793 },
8794#ifdef WLAN_FEATURE_APFIND
8795 {
8796 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8797 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8798 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8799 WIPHY_VENDOR_CMD_NEED_NETDEV,
8800 .doit = wlan_hdd_cfg80211_apfind_cmd
8801 },
8802#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308803 {
8804 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8805 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8806 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8807 WIPHY_VENDOR_CMD_NEED_NETDEV |
8808 WIPHY_VENDOR_CMD_NEED_RUNNING,
8809 .doit = wlan_hdd_cfg80211_set_nud_stats
8810 },
8811 {
8812 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8813 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8814 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8815 WIPHY_VENDOR_CMD_NEED_NETDEV |
8816 WIPHY_VENDOR_CMD_NEED_RUNNING,
8817 .doit = wlan_hdd_cfg80211_get_nud_stats
8818 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308819 {
8820 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8821 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8822 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8823 WIPHY_VENDOR_CMD_NEED_NETDEV |
8824 WIPHY_VENDOR_CMD_NEED_RUNNING,
8825 .doit = hdd_cfg80211_get_station_cmd
8826 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308827 {
8828 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8829 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8830 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308831 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308832 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8833 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308834};
8835
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008836/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308837static const
8838struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008839{
8840#ifdef FEATURE_WLAN_CH_AVOID
8841 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308842 .vendor_id = QCA_NL80211_VENDOR_ID,
8843 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008844 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308845#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8846#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8847 {
8848 /* Index = 1*/
8849 .vendor_id = QCA_NL80211_VENDOR_ID,
8850 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8851 },
8852 {
8853 /* Index = 2*/
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8856 },
8857 {
8858 /* Index = 3*/
8859 .vendor_id = QCA_NL80211_VENDOR_ID,
8860 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8861 },
8862 {
8863 /* Index = 4*/
8864 .vendor_id = QCA_NL80211_VENDOR_ID,
8865 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8866 },
8867 {
8868 /* Index = 5*/
8869 .vendor_id = QCA_NL80211_VENDOR_ID,
8870 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8871 },
8872 {
8873 /* Index = 6*/
8874 .vendor_id = QCA_NL80211_VENDOR_ID,
8875 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8876 },
8877#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308878#ifdef WLAN_FEATURE_EXTSCAN
8879 {
8880 .vendor_id = QCA_NL80211_VENDOR_ID,
8881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8882 },
8883 {
8884 .vendor_id = QCA_NL80211_VENDOR_ID,
8885 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8886 },
8887 {
8888 .vendor_id = QCA_NL80211_VENDOR_ID,
8889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8890 },
8891 {
8892 .vendor_id = QCA_NL80211_VENDOR_ID,
8893 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8894 },
8895 {
8896 .vendor_id = QCA_NL80211_VENDOR_ID,
8897 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8898 },
8899 {
8900 .vendor_id = QCA_NL80211_VENDOR_ID,
8901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8902 },
8903 {
8904 .vendor_id = QCA_NL80211_VENDOR_ID,
8905 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8906 },
8907 {
8908 .vendor_id = QCA_NL80211_VENDOR_ID,
8909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8910 },
8911 {
8912 .vendor_id = QCA_NL80211_VENDOR_ID,
8913 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8914 },
8915 {
8916 .vendor_id = QCA_NL80211_VENDOR_ID,
8917 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8918 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308919#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308920/*EXT TDLS*/
8921 {
8922 .vendor_id = QCA_NL80211_VENDOR_ID,
8923 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8924 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308925 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8926 .vendor_id = QCA_NL80211_VENDOR_ID,
8927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8928 },
8929
Srinivas Dasari030bad32015-02-18 23:23:54 +05308930
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308931 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308932 .vendor_id = QCA_NL80211_VENDOR_ID,
8933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8934 },
8935
Sushant Kaushik084f6592015-09-10 13:11:56 +05308936 {
8937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308939 },
8940 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8941 .vendor_id = QCA_NL80211_VENDOR_ID,
8942 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8943 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308944 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8945 .vendor_id = QCA_NL80211_VENDOR_ID,
8946 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8947 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308948 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8949 .vendor_id = QCA_NL80211_VENDOR_ID,
8950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8951 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308952 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8953 .vendor_id = QCA_NL80211_VENDOR_ID,
8954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8955 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308956 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8957 .vendor_id = QCA_NL80211_VENDOR_ID,
8958 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8959 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008960};
8961
Jeff Johnson295189b2012-06-20 16:38:30 -07008962/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308963 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308964 * This function is called by hdd_wlan_startup()
8965 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308966 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308968struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008969{
8970 struct wiphy *wiphy;
8971 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308972 /*
8973 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 */
8975 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8976
8977 if (!wiphy)
8978 {
8979 /* Print error and jump into err label and free the memory */
8980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8981 return NULL;
8982 }
8983
Sunil Duttc69bccb2014-05-26 21:30:20 +05308984
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 return wiphy;
8986}
8987
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308988#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8989 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8990/**
8991 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8992 * @wiphy: pointer to wiphy
8993 * @config: pointer to config
8994 *
8995 * Return: None
8996 */
8997static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8998 hdd_config_t *config)
8999{
9000 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9001 if (config->max_sched_scan_plan_interval)
9002 wiphy->max_sched_scan_plan_interval =
9003 config->max_sched_scan_plan_interval;
9004 if (config->max_sched_scan_plan_iterations)
9005 wiphy->max_sched_scan_plan_iterations =
9006 config->max_sched_scan_plan_iterations;
9007}
9008#else
9009static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9010 hdd_config_t *config)
9011{
9012}
9013#endif
9014
Jeff Johnson295189b2012-06-20 16:38:30 -07009015/*
9016 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309017 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 * private ioctl to change the band value
9019 */
9020int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9021{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309022 int i, j;
9023 eNVChannelEnabledType channelEnabledState;
9024
Jeff Johnsone7245742012-09-05 17:12:55 -07009025 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309026
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309027 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309029
9030 if (NULL == wiphy->bands[i])
9031 {
9032 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9033 __func__, i);
9034 continue;
9035 }
9036
9037 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9038 {
9039 struct ieee80211_supported_band *band = wiphy->bands[i];
9040
9041 channelEnabledState = vos_nv_getChannelEnabledState(
9042 band->channels[j].hw_value);
9043
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309044 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309045 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309046 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309047 continue;
9048 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309049 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309050 {
9051 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9052 continue;
9053 }
9054
9055 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9056 NV_CHANNEL_INVALID == channelEnabledState)
9057 {
9058 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9059 }
9060 else if (NV_CHANNEL_DFS == channelEnabledState)
9061 {
9062 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9063 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9064 }
9065 else
9066 {
9067 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9068 |IEEE80211_CHAN_RADAR);
9069 }
9070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009071 }
9072 return 0;
9073}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309074
9075/**
9076 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9077 * @wiphy: Pointer to the wiphy.
9078 *
9079 * This Function adds Channel Switch support flag, if channel switch is
9080 * supported by kernel.
9081 * Return: void.
9082 */
9083#ifdef CHANNEL_SWITCH_SUPPORTED
9084static inline
9085void hdd_add_channel_switch_support(struct wiphy *wiphy)
9086{
9087 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9088 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9089}
9090#else
9091static inline
9092void hdd_add_channel_switch_support(struct wiphy *wiphy)
9093{
9094}
9095#endif
9096
Jeff Johnson295189b2012-06-20 16:38:30 -07009097/*
9098 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309099 * This function is called by hdd_wlan_startup()
9100 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 * This function is used to initialize and register wiphy structure.
9102 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309103int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 struct wiphy *wiphy,
9105 hdd_config_t *pCfg
9106 )
9107{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309108 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309109 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9110
Jeff Johnsone7245742012-09-05 17:12:55 -07009111 ENTER();
9112
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 /* Now bind the underlying wlan device with wiphy */
9114 set_wiphy_dev(wiphy, dev);
9115
9116 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009117
Kiet Lam6c583332013-10-14 05:37:09 +05309118#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009119 /* the flag for the other case would be initialzed in
9120 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9122 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9123#else
Amar Singhal0a402232013-10-11 20:57:16 -07009124 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309125#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309126#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009127
Amar Singhalfddc28c2013-09-05 13:03:40 -07009128 /* This will disable updating of NL channels from passive to
9129 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309130#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9131 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9132#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009133 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309134#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009135
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9137 wiphy->wowlan = &wowlan_support_cfg80211_init;
9138#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309139 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9140 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309141 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9142 wiphy->wowlan.pattern_min_len = 1;
9143 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9144#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009145
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009147 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9148 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9149 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009150 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309152 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309153#else
9154 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9155#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009156#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009157
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009158#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009159 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009160#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009161 || pCfg->isFastRoamIniFeatureEnabled
9162#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009163#ifdef FEATURE_WLAN_ESE
9164 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009165#endif
9166 )
9167 {
9168 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9169 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009170#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009171#ifdef FEATURE_WLAN_TDLS
9172 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9173 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9174#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309175#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309176 if (pCfg->configPNOScanSupport)
9177 {
9178 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9179 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9180 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9181 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9182 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309183#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009184
Abhishek Singh10d85972015-04-17 10:27:23 +05309185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9186 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9187#endif
9188
Amar Singhalfddc28c2013-09-05 13:03:40 -07009189#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009190 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9191 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009192 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009193 driver need to determine what to do with both
9194 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009195
9196 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009197#else
9198 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009199#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009200
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309201 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9202
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309203 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309205 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9206
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309208 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9209 | BIT(NL80211_IFTYPE_ADHOC)
9210 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9211 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309212 | BIT(NL80211_IFTYPE_AP)
9213 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009214
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309215 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009216 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9218 if( pCfg->enableMCC )
9219 {
9220 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309221 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009222
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309223 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309224 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009225
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309226 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309227 wiphy->iface_combinations = wlan_hdd_iface_combination;
9228 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009229#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309230 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009231
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 /* Before registering we need to update the ht capabilitied based
9233 * on ini values*/
9234 if( !pCfg->ShortGI20MhzEnable )
9235 {
9236 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9237 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 }
9239
9240 if( !pCfg->ShortGI40MhzEnable )
9241 {
9242 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9243 }
9244
9245 if( !pCfg->nChannelBondingMode5GHz )
9246 {
9247 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9248 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309249 /*
9250 * In case of static linked driver at the time of driver unload,
9251 * module exit doesn't happens. Module cleanup helps in cleaning
9252 * of static memory.
9253 * If driver load happens statically, at the time of driver unload,
9254 * wiphy flags don't get reset because of static memory.
9255 * It's better not to store channel in static memory.
9256 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309257 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9258 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309259 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309260 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309261 {
9262 hddLog(VOS_TRACE_LEVEL_ERROR,
9263 FL("Not enough memory to allocate channels"));
9264 return -ENOMEM;
9265 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309266 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309267 &hdd_channels_2_4_GHZ[0],
9268 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009269
Agrawal Ashish97dec502015-11-26 20:20:58 +05309270 if (true == hdd_is_5g_supported(pHddCtx))
9271 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309272 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9273 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309274 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309275 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309276 {
9277 hddLog(VOS_TRACE_LEVEL_ERROR,
9278 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309279 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9280 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309281 return -ENOMEM;
9282 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309283 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309284 &hdd_channels_5_GHZ[0],
9285 sizeof(hdd_channels_5_GHZ));
9286 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309287
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309288 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309289 {
9290
9291 if (NULL == wiphy->bands[i])
9292 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309293 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309294 __func__, i);
9295 continue;
9296 }
9297
9298 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9299 {
9300 struct ieee80211_supported_band *band = wiphy->bands[i];
9301
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309302 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309303 {
9304 // Enable social channels for P2P
9305 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9306 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9307 else
9308 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9309 continue;
9310 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309311 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309312 {
9313 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9314 continue;
9315 }
9316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 }
9318 /*Initialise the supported cipher suite details*/
9319 wiphy->cipher_suites = hdd_cipher_suites;
9320 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9321
9322 /*signal strength in mBm (100*dBm) */
9323 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9324
9325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309326 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009328
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309329 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309330 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9331 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009332 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9333 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9334
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309335 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9336
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309337 EXIT();
9338 return 0;
9339}
9340
9341/* In this function we are registering wiphy. */
9342int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9343{
9344 ENTER();
9345 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 if (0 > wiphy_register(wiphy))
9347 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309348 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9350 return -EIO;
9351 }
9352
9353 EXIT();
9354 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355}
Jeff Johnson295189b2012-06-20 16:38:30 -07009356
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309357/* In this function we are updating channel list when,
9358 regulatory domain is FCC and country code is US.
9359 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9360 As per FCC smart phone is not a indoor device.
9361 GO should not opeate on indoor channels */
9362void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9363{
9364 int j;
9365 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9366 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9367 //Default counrtycode from NV at the time of wiphy initialization.
9368 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9369 &defaultCountryCode[0]))
9370 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009371 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309372 }
9373 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9374 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309375 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309376 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309377 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309378 return;
9379 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309380 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309381 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309382 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309383 // Mark UNII -1 band channel as passive
9384 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9385 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9386 }
9387 }
9388}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309389/* This function registers for all frame which supplicant is interested in */
9390void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009391{
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9393 /* Register for all P2P action, public action etc frames */
9394 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009395 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309396 /* Register frame indication call back */
9397 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 /* Right now we are registering these frame when driver is getting
9399 initialized. Once we will move to 2.6.37 kernel, in which we have
9400 frame register ops, we will move this code as a part of that */
9401 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309402 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9404
9405 /* GAS Initial Response */
9406 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9407 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 /* GAS Comeback Request */
9410 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9411 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9412
9413 /* GAS Comeback Response */
9414 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9415 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9416
9417 /* P2P Public Action */
9418 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 P2P_PUBLIC_ACTION_FRAME_SIZE );
9421
9422 /* P2P Action */
9423 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9424 (v_U8_t*)P2P_ACTION_FRAME,
9425 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009426
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309427 /* WNM BSS Transition Request frame */
9428 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9429 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9430 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009431
9432 /* WNM-Notification */
9433 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9434 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9435 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009436}
9437
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309438void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009439{
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9441 /* Register for all P2P action, public action etc frames */
9442 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9443
Jeff Johnsone7245742012-09-05 17:12:55 -07009444 ENTER();
9445
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 /* Right now we are registering these frame when driver is getting
9447 initialized. Once we will move to 2.6.37 kernel, in which we have
9448 frame register ops, we will move this code as a part of that */
9449 /* GAS Initial Request */
9450
9451 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9452 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9453
9454 /* GAS Initial Response */
9455 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9456 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309457
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 /* GAS Comeback Request */
9459 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9460 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9461
9462 /* GAS Comeback Response */
9463 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9464 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9465
9466 /* P2P Public Action */
9467 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309468 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 P2P_PUBLIC_ACTION_FRAME_SIZE );
9470
9471 /* P2P Action */
9472 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9473 (v_U8_t*)P2P_ACTION_FRAME,
9474 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009475 /* WNM-Notification */
9476 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9477 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9478 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009479}
9480
9481#ifdef FEATURE_WLAN_WAPI
9482void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309483 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009484{
9485 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9486 tCsrRoamSetKey setKey;
9487 v_BOOL_t isConnected = TRUE;
9488 int status = 0;
9489 v_U32_t roamId= 0xFF;
9490 tANI_U8 *pKeyPtr = NULL;
9491 int n = 0;
9492
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309493 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9494 __func__, hdd_device_modetoString(pAdapter->device_mode),
9495 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009496
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309497 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 setKey.keyId = key_index; // Store Key ID
9499 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9500 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9501 setKey.paeRole = 0 ; // the PAE role
9502 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9503 {
9504 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9505 }
9506 else
9507 {
9508 isConnected = hdd_connIsConnected(pHddStaCtx);
9509 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9510 }
9511 setKey.keyLength = key_Len;
9512 pKeyPtr = setKey.Key;
9513 memcpy( pKeyPtr, key, key_Len);
9514
Arif Hussain6d2a3322013-11-17 19:50:10 -08009515 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 __func__, key_Len);
9517 for (n = 0 ; n < key_Len; n++)
9518 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9519 __func__,n,setKey.Key[n]);
9520
9521 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9522 if ( isConnected )
9523 {
9524 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9525 pAdapter->sessionId, &setKey, &roamId );
9526 }
9527 if ( status != 0 )
9528 {
9529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9530 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9531 __LINE__, status );
9532 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9533 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309534 /* Need to clear any trace of key value in the memory.
9535 * Thus zero out the memory even though it is local
9536 * variable.
9537 */
9538 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009539}
9540#endif /* FEATURE_WLAN_WAPI*/
9541
9542#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 beacon_data_t **ppBeacon,
9545 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009546#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009548 beacon_data_t **ppBeacon,
9549 struct cfg80211_beacon_data *params,
9550 int dtim_period)
9551#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552{
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 int size;
9554 beacon_data_t *beacon = NULL;
9555 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309556 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9557 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Jeff Johnsone7245742012-09-05 17:12:55 -07009559 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309561 {
9562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9563 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009566
9567 old = pAdapter->sessionCtx.ap.beacon;
9568
9569 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309570 {
9571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9572 FL("session(%d) old and new heads points to NULL"),
9573 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309575 }
9576
9577 if (params->tail && !params->tail_len)
9578 {
9579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9580 FL("tail_len is zero but tail is not NULL"));
9581 return -EINVAL;
9582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9585 /* Kernel 3.0 is not updating dtim_period for set beacon */
9586 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309587 {
9588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9589 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009592#endif
9593
Kapil Gupta137ef892016-12-13 19:38:00 +05309594 if (params->head)
9595 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309597 head = params->head;
9598 } else
9599 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309601 head = old->head;
9602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
Kapil Gupta137ef892016-12-13 19:38:00 +05309604 if (params->tail || !old)
9605 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309607 tail = params->tail;
9608 } else
9609 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309611 tail = old->tail;
9612 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009613
Kapil Gupta137ef892016-12-13 19:38:00 +05309614 if (params->proberesp_ies || !old)
9615 {
9616 proberesp_ies_len = params->proberesp_ies_len;
9617 proberesp_ies = params->proberesp_ies;
9618 } else
9619 {
9620 proberesp_ies_len = old->proberesp_ies_len;
9621 proberesp_ies = old->proberesp_ies;
9622 }
9623
9624 if (params->assocresp_ies || !old)
9625 {
9626 assocresp_ies_len = params->assocresp_ies_len;
9627 assocresp_ies = params->assocresp_ies;
9628 } else
9629 {
9630 assocresp_ies_len = old->assocresp_ies_len;
9631 assocresp_ies = old->assocresp_ies;
9632 }
9633
9634 size = sizeof(beacon_data_t) + head_len + tail_len +
9635 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009636
9637 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309639 {
9640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9641 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309643 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009644
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009645#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309646 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 beacon->dtim_period = params->dtim_period;
9648 else
9649 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009650#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309651 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009652 beacon->dtim_period = dtim_period;
9653 else
9654 beacon->dtim_period = old->dtim_period;
9655#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309656
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9658 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 beacon->proberesp_ies = beacon->tail + tail_len;
9660 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 beacon->head_len = head_len;
9663 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309664 beacon->proberesp_ies_len = proberesp_ies_len;
9665 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
c_manjee527ecac2017-01-25 12:25:27 +05309667 if (head && head_len)
9668 memcpy(beacon->head, head, head_len);
9669 if (tail && tail_len)
9670 memcpy(beacon->tail, tail, tail_len);
9671 if (proberesp_ies && proberesp_ies_len)
9672 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9673 if (assocresp_ies && assocresp_ies_len)
9674 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
9676 *ppBeacon = beacon;
9677
9678 kfree(old);
9679
9680 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681}
Jeff Johnson295189b2012-06-20 16:38:30 -07009682
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309683v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9685 const v_U8_t *pIes,
9686#else
9687 v_U8_t *pIes,
9688#endif
9689 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009690{
9691 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309692 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309694
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309696 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 elem_id = ptr[0];
9698 elem_len = ptr[1];
9699 left -= 2;
9700 if(elem_len > left)
9701 {
9702 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009703 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 eid,elem_len,left);
9705 return NULL;
9706 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309707 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 {
9709 return ptr;
9710 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309711
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 left -= elem_len;
9713 ptr += (elem_len + 2);
9714 }
9715 return NULL;
9716}
9717
Jeff Johnson295189b2012-06-20 16:38:30 -07009718/* Check if rate is 11g rate or not */
9719static int wlan_hdd_rate_is_11g(u8 rate)
9720{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009721 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 u8 i;
9723 for (i = 0; i < 8; i++)
9724 {
9725 if(rate == gRateArray[i])
9726 return TRUE;
9727 }
9728 return FALSE;
9729}
9730
9731/* Check for 11g rate and set proper 11g only mode */
9732static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9733 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9734{
9735 u8 i, num_rates = pIe[0];
9736
9737 pIe += 1;
9738 for ( i = 0; i < num_rates; i++)
9739 {
9740 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9741 {
9742 /* If rate set have 11g rate than change the mode to 11G */
9743 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9744 if (pIe[i] & BASIC_RATE_MASK)
9745 {
9746 /* If we have 11g rate as basic rate, it means mode
9747 is 11g only mode.
9748 */
9749 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9750 *pCheckRatesfor11g = FALSE;
9751 }
9752 }
9753 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9754 {
9755 *require_ht = TRUE;
9756 }
9757 }
9758 return;
9759}
9760
9761static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9762{
9763 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9764 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9765 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9766 u8 checkRatesfor11g = TRUE;
9767 u8 require_ht = FALSE;
9768 u8 *pIe=NULL;
9769
9770 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9771
9772 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9773 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9774 if (pIe != NULL)
9775 {
9776 pIe += 1;
9777 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9778 &pConfig->SapHw_mode);
9779 }
9780
9781 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9782 WLAN_EID_EXT_SUPP_RATES);
9783 if (pIe != NULL)
9784 {
9785
9786 pIe += 1;
9787 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9788 &pConfig->SapHw_mode);
9789 }
9790
9791 if( pConfig->channel > 14 )
9792 {
9793 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9794 }
9795
9796 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9797 WLAN_EID_HT_CAPABILITY);
9798
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309799 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 {
9801 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9802 if(require_ht)
9803 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9804 }
9805}
9806
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309807static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9808 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9809{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009810 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309811 v_U8_t *pIe = NULL;
9812 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9813
9814 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9815 pBeacon->tail, pBeacon->tail_len);
9816
9817 if (pIe)
9818 {
9819 ielen = pIe[1] + 2;
9820 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9821 {
9822 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9823 }
9824 else
9825 {
9826 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9827 return -EINVAL;
9828 }
9829 *total_ielen += ielen;
9830 }
9831 return 0;
9832}
9833
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009834static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9835 v_U8_t *genie, v_U8_t *total_ielen)
9836{
9837 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9838 int left = pBeacon->tail_len;
9839 v_U8_t *ptr = pBeacon->tail;
9840 v_U8_t elem_id, elem_len;
9841 v_U16_t ielen = 0;
9842
9843 if ( NULL == ptr || 0 == left )
9844 return;
9845
9846 while (left >= 2)
9847 {
9848 elem_id = ptr[0];
9849 elem_len = ptr[1];
9850 left -= 2;
9851 if (elem_len > left)
9852 {
9853 hddLog( VOS_TRACE_LEVEL_ERROR,
9854 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9855 elem_id, elem_len, left);
9856 return;
9857 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309858 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009859 {
9860 /* skipping the VSIE's which we don't want to include or
9861 * it will be included by existing code
9862 */
9863 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9864#ifdef WLAN_FEATURE_WFD
9865 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9866#endif
9867 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9868 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9869 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9870 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9871 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9872 {
9873 ielen = ptr[1] + 2;
9874 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9875 {
9876 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9877 *total_ielen += ielen;
9878 }
9879 else
9880 {
9881 hddLog( VOS_TRACE_LEVEL_ERROR,
9882 "IE Length is too big "
9883 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9884 elem_id, elem_len, *total_ielen);
9885 }
9886 }
9887 }
9888
9889 left -= elem_len;
9890 ptr += (elem_len + 2);
9891 }
9892 return;
9893}
9894
Kapil Gupta137ef892016-12-13 19:38:00 +05309895int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009896{
9897 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309898 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009900 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309901 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009902
9903 genie = vos_mem_malloc(MAX_GENIE_LEN);
9904
9905 if(genie == NULL) {
9906
9907 return -ENOMEM;
9908 }
9909
Kapil Gupta137ef892016-12-13 19:38:00 +05309910 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309911 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9912 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309914 hddLog(LOGE,
9915 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309916 ret = -EINVAL;
9917 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 }
9919
9920#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309921 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9922 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9923 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309924 hddLog(LOGE,
9925 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309926 ret = -EINVAL;
9927 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 }
9929#endif
9930
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309931 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9932 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309934 hddLog(LOGE,
9935 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309936 ret = -EINVAL;
9937 goto done;
9938 }
9939
9940 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9941 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009942 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009944
9945 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9946 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9947 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9948 {
9949 hddLog(LOGE,
9950 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009951 ret = -EINVAL;
9952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 }
9954
9955 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9956 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9957 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9958 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9959 ==eHAL_STATUS_FAILURE)
9960 {
9961 hddLog(LOGE,
9962 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009963 ret = -EINVAL;
9964 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 }
9966
9967 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309968 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309970 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 u8 probe_rsp_ie_len[3] = {0};
9972 u8 counter = 0;
9973 /* Check Probe Resp Length if it is greater then 255 then Store
9974 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9975 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9976 Store More then 255 bytes into One Variable.
9977 */
9978 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9979 {
9980 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9981 {
9982 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9983 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9984 }
9985 else
9986 {
9987 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9988 rem_probe_resp_ie_len = 0;
9989 }
9990 }
9991
9992 rem_probe_resp_ie_len = 0;
9993
9994 if (probe_rsp_ie_len[0] > 0)
9995 {
9996 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9997 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309998 (tANI_U8*)&pBeacon->
9999 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 probe_rsp_ie_len[0], NULL,
10001 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10002 {
10003 hddLog(LOGE,
10004 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010005 ret = -EINVAL;
10006 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 }
10008 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10009 }
10010
10011 if (probe_rsp_ie_len[1] > 0)
10012 {
10013 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10014 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010015 (tANI_U8*)&pBeacon->
10016 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 probe_rsp_ie_len[1], NULL,
10018 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10019 {
10020 hddLog(LOGE,
10021 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010022 ret = -EINVAL;
10023 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 }
10025 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10026 }
10027
10028 if (probe_rsp_ie_len[2] > 0)
10029 {
10030 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10031 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010032 (tANI_U8*)&pBeacon->
10033 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 probe_rsp_ie_len[2], NULL,
10035 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10036 {
10037 hddLog(LOGE,
10038 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010039 ret = -EINVAL;
10040 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 }
10042 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10043 }
10044
10045 if (probe_rsp_ie_len[1] == 0 )
10046 {
10047 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10048 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10049 eANI_BOOLEAN_FALSE) )
10050 {
10051 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010052 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 }
10054 }
10055
10056 if (probe_rsp_ie_len[2] == 0 )
10057 {
10058 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10059 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10060 eANI_BOOLEAN_FALSE) )
10061 {
10062 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010063 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 }
10065 }
10066
10067 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10068 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10069 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10070 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10071 == eHAL_STATUS_FAILURE)
10072 {
10073 hddLog(LOGE,
10074 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010075 ret = -EINVAL;
10076 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 }
10078 }
10079 else
10080 {
10081 // Reset WNI_CFG_PROBE_RSP Flags
10082 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10083
10084 hddLog(VOS_TRACE_LEVEL_INFO,
10085 "%s: No Probe Response IE received in set beacon",
10086 __func__);
10087 }
10088
10089 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010090 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 {
10092 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010093 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10094 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10096 {
10097 hddLog(LOGE,
10098 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010099 ret = -EINVAL;
10100 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 }
10102
10103 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10104 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10105 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10106 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10107 == eHAL_STATUS_FAILURE)
10108 {
10109 hddLog(LOGE,
10110 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010111 ret = -EINVAL;
10112 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 }
10114 }
10115 else
10116 {
10117 hddLog(VOS_TRACE_LEVEL_INFO,
10118 "%s: No Assoc Response IE received in set beacon",
10119 __func__);
10120
10121 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10122 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10123 eANI_BOOLEAN_FALSE) )
10124 {
10125 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 }
10128 }
10129
Jeff Johnsone7245742012-09-05 17:12:55 -070010130done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010132 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133}
Jeff Johnson295189b2012-06-20 16:38:30 -070010134
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010135/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 * FUNCTION: wlan_hdd_validate_operation_channel
10137 * called by wlan_hdd_cfg80211_start_bss() and
10138 * wlan_hdd_cfg80211_set_channel()
10139 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010140 * channel list.
10141 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010142VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010143{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010144
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 v_U32_t num_ch = 0;
10146 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10147 u32 indx = 0;
10148 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010149 v_U8_t fValidChannel = FALSE, count = 0;
10150 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010151
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10153
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010154 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010156 /* Validate the channel */
10157 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010159 if ( channel == rfChannels[count].channelNum )
10160 {
10161 fValidChannel = TRUE;
10162 break;
10163 }
10164 }
10165 if (fValidChannel != TRUE)
10166 {
10167 hddLog(VOS_TRACE_LEVEL_ERROR,
10168 "%s: Invalid Channel [%d]", __func__, channel);
10169 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010170 }
10171 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010172 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010174 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10175 valid_ch, &num_ch))
10176 {
10177 hddLog(VOS_TRACE_LEVEL_ERROR,
10178 "%s: failed to get valid channel list", __func__);
10179 return VOS_STATUS_E_FAILURE;
10180 }
10181 for (indx = 0; indx < num_ch; indx++)
10182 {
10183 if (channel == valid_ch[indx])
10184 {
10185 break;
10186 }
10187 }
10188
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010189 if (indx >= num_ch)
10190 {
10191 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10192 {
10193 eCsrBand band;
10194 unsigned int freq;
10195
10196 sme_GetFreqBand(hHal, &band);
10197
10198 if (eCSR_BAND_5G == band)
10199 {
10200#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10201 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10202 {
10203 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010204 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010205 }
10206 else
10207 {
10208 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010209 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010210 }
10211#else
10212 freq = ieee80211_channel_to_frequency(channel);
10213#endif
10214 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10215 return VOS_STATUS_SUCCESS;
10216 }
10217 }
10218
10219 hddLog(VOS_TRACE_LEVEL_ERROR,
10220 "%s: Invalid Channel [%d]", __func__, channel);
10221 return VOS_STATUS_E_FAILURE;
10222 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010224
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010226
Jeff Johnson295189b2012-06-20 16:38:30 -070010227}
10228
Viral Modi3a32cc52013-02-08 11:14:52 -080010229/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010230 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010231 * This function is used to set the channel number
10232 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010233static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010234 struct ieee80211_channel *chan,
10235 enum nl80211_channel_type channel_type
10236 )
10237{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010238 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010239 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010240 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010241 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010242 hdd_context_t *pHddCtx;
10243 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010244
10245 ENTER();
10246
10247 if( NULL == dev )
10248 {
10249 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010250 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010251 return -ENODEV;
10252 }
10253 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010254
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10256 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10257 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010258 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010259 "%s: device_mode = %s (%d) freq = %d", __func__,
10260 hdd_device_modetoString(pAdapter->device_mode),
10261 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010262
10263 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10264 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010265 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010266 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010267 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010268 }
10269
10270 /*
10271 * Do freq to chan conversion
10272 * TODO: for 11a
10273 */
10274
10275 channel = ieee80211_frequency_to_channel(freq);
10276
10277 /* Check freq range */
10278 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10279 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10280 {
10281 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010282 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010283 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10284 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10285 return -EINVAL;
10286 }
10287
10288 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10289
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010290 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10291 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010292 {
10293 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10294 {
10295 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010296 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010297 return -EINVAL;
10298 }
10299 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10300 "%s: set channel to [%d] for device mode =%d",
10301 __func__, channel,pAdapter->device_mode);
10302 }
10303 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010304 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010305 )
10306 {
10307 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10308 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10309 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10310
10311 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10312 {
10313 /* Link is up then return cant set channel*/
10314 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010315 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010316 return -EINVAL;
10317 }
10318
10319 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10320 pHddStaCtx->conn_info.operationChannel = channel;
10321 pRoamProfile->ChannelInfo.ChannelList =
10322 &pHddStaCtx->conn_info.operationChannel;
10323 }
10324 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010325 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010326 )
10327 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010328 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10329 {
10330 if(VOS_STATUS_SUCCESS !=
10331 wlan_hdd_validate_operation_channel(pAdapter,channel))
10332 {
10333 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010334 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010335 return -EINVAL;
10336 }
10337 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10338 }
10339 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010340 {
10341 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10342
10343 /* If auto channel selection is configured as enable/ 1 then ignore
10344 channel set by supplicant
10345 */
10346 if ( cfg_param->apAutoChannelSelection )
10347 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010348 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10349 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010350 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010351 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10352 __func__, hdd_device_modetoString(pAdapter->device_mode),
10353 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010354 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010355 else
10356 {
10357 if(VOS_STATUS_SUCCESS !=
10358 wlan_hdd_validate_operation_channel(pAdapter,channel))
10359 {
10360 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010361 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010362 return -EINVAL;
10363 }
10364 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10365 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010366 }
10367 }
10368 else
10369 {
10370 hddLog(VOS_TRACE_LEVEL_FATAL,
10371 "%s: Invalid device mode failed to set valid channel", __func__);
10372 return -EINVAL;
10373 }
10374 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010375 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010376}
10377
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010378static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10379 struct net_device *dev,
10380 struct ieee80211_channel *chan,
10381 enum nl80211_channel_type channel_type
10382 )
10383{
10384 int ret;
10385
10386 vos_ssr_protect(__func__);
10387 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10388 vos_ssr_unprotect(__func__);
10389
10390 return ret;
10391}
10392
Anurag Chouhan83026002016-12-13 22:46:21 +053010393#ifdef DHCP_SERVER_OFFLOAD
10394void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10395 VOS_STATUS status)
10396{
10397 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10398
10399 ENTER();
10400
10401 if (NULL == adapter)
10402 {
10403 hddLog(VOS_TRACE_LEVEL_ERROR,
10404 "%s: adapter is NULL",__func__);
10405 return;
10406 }
10407
10408 adapter->dhcp_status.dhcp_offload_status = status;
10409 vos_event_set(&adapter->dhcp_status.vos_event);
10410 return;
10411}
10412
10413/**
10414 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10415 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010416 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010417 *
10418 * Return: None
10419 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010420VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10421 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010422{
10423 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10424 sir_dhcp_srv_offload_info dhcp_srv_info;
10425 tANI_U8 num_entries = 0;
10426 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10427 tANI_U8 num;
10428 tANI_U32 temp;
10429 VOS_STATUS ret;
10430
10431 ENTER();
10432
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010433 if (!re_init) {
10434 ret = wlan_hdd_validate_context(hdd_ctx);
10435 if (0 != ret)
10436 return VOS_STATUS_E_INVAL;
10437 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010438
10439 /* Prepare the request to send to SME */
10440 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10441 if (NULL == dhcp_srv_info) {
10442 hddLog(VOS_TRACE_LEVEL_ERROR,
10443 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10444 return VOS_STATUS_E_NOMEM;
10445 }
10446
10447 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10448
10449 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10450 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10451 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10452 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10453 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10454 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10455
10456 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10457 srv_ip,
10458 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010459 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010460 if (num_entries != IPADDR_NUM_ENTRIES) {
10461 hddLog(VOS_TRACE_LEVEL_ERROR,
10462 "%s: incorrect IP address (%s) assigned for DHCP server!",
10463 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10464 vos_mem_free(dhcp_srv_info);
10465 return VOS_STATUS_E_FAILURE;
10466 }
10467
10468 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10469 hddLog(VOS_TRACE_LEVEL_ERROR,
10470 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10471 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10472 vos_mem_free(dhcp_srv_info);
10473 return VOS_STATUS_E_FAILURE;
10474 }
10475
10476 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10477 hddLog(VOS_TRACE_LEVEL_ERROR,
10478 "%s: invalid IP address (%s)! The last field must be less than 100!",
10479 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10480 vos_mem_free(dhcp_srv_info);
10481 return VOS_STATUS_E_FAILURE;
10482 }
10483
10484 for (num = 0; num < num_entries; num++) {
10485 temp = srv_ip[num];
10486 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10487 }
10488
10489 if (eHAL_STATUS_SUCCESS !=
10490 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10491 hddLog(VOS_TRACE_LEVEL_ERROR,
10492 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10493 vos_mem_free(dhcp_srv_info);
10494 return VOS_STATUS_E_FAILURE;
10495 }
10496
10497 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10498 "%s: enable DHCP Server offload successfully!", __func__);
10499
10500 vos_mem_free(dhcp_srv_info);
10501 return 0;
10502}
10503#endif /* DHCP_SERVER_OFFLOAD */
10504
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010505/*
10506 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10507 * @wiphy_chan: wiphy channel number
10508 * @rfChannel: channel hw value
10509 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010510 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010511 *
10512 * Modify wiphy flags and cds state if channel is indoor.
10513 *
10514 * Return: void
10515 */
10516void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010517 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010518{
10519 v_U32_t channelLoop;
10520 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10521
10522 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10523
10524 if (rfChannels[channelLoop].channelNum == rfChannel) {
10525 channelEnum = (eRfChannels)channelLoop;
10526 break;
10527 }
10528 }
10529
10530 if (INVALID_RF_CHANNEL == channelEnum)
10531 return;
10532
10533 if (disable) {
10534 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10535 wiphy_chan->flags |=
10536 IEEE80211_CHAN_DISABLED;
10537 regChannels[channelEnum].enabled =
10538 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010539 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10540 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010541 }
10542 } else {
10543 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10544 wiphy_chan->flags &=
10545 ~IEEE80211_CHAN_DISABLED;
10546 /*
10547 * Indoor channels are marked as DFS
10548 * during regulatory processing
10549 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010550 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10551 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10552 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10553 && (wiphy_chan->flags &
10554 IEEE80211_CHAN_INDOOR_ONLY))) {
10555 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10556 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10557 channelEnum);
10558 } else {
10559 regChannels[channelEnum].enabled =
10560 NV_CHANNEL_ENABLE;
10561 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10562 channelEnum);
10563 }
10564 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010565
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010566 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010567}
10568
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010569void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010570{
10571 int band_num;
10572 int chan_num;
10573 v_U32_t rfChannel;
10574 struct ieee80211_channel *wiphy_chan;
10575 struct wiphy *wiphy;
10576
10577 ENTER();
10578 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10579
10580 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010581 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010582
10583 if (wiphy->bands[band_num] == NULL)
10584 continue;
10585
10586 for (chan_num = 0;
10587 chan_num < wiphy->bands[band_num]->n_channels;
10588 chan_num++) {
10589
10590 wiphy_chan =
10591 &(wiphy->bands[band_num]->channels[chan_num]);
10592 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10593
10594 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010595 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010596 }
10597 }
10598 EXIT();
10599}
10600
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010601int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10602{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010603 eHalStatus status;
10604 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010605 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10606 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10607 long ret;
10608 eConnectionState prev_conn_state;
10609 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10610
10611 ENTER();
10612
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010613 /* Indicate sme of disconnect so that in progress connection or preauth
10614 * can be aborted
10615 */
10616 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10617 pAdapter->sessionId);
10618 pHddCtx->isAmpAllowed = VOS_TRUE;
10619
10620 /* Need to apply spin lock before decreasing active sessions
10621 * as there can be chance for double decrement if context switch
10622 * Calls hdd_DisConnectHandler.
10623 */
10624
10625 prev_conn_state = pHddStaCtx->conn_info.connState;
10626
10627 spin_lock_bh(&pAdapter->lock_for_active_session);
10628 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10629 {
10630 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10631 }
10632 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10633 spin_unlock_bh(&pAdapter->lock_for_active_session);
10634 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10635
10636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10637 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10638
10639 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10640
10641 /*
10642 * stop tx queues before deleting STA/BSS context from the firmware.
10643 * tx has to be disabled because the firmware can get busy dropping
10644 * the tx frames after BSS/STA has been deleted and will not send
10645 * back a response resulting in WDI timeout
10646 */
10647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10648 netif_tx_disable(pAdapter->dev);
10649 netif_carrier_off(pAdapter->dev);
10650
10651 wlan_hdd_check_and_stop_mon(pAdapter, true);
10652
10653 /*issue disconnect*/
10654 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10655 pAdapter->sessionId, reason);
10656 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10657 prev_conn_state != eConnectionState_Connecting)
10658 {
10659 hddLog(LOG1,
10660 FL("status = %d, already disconnected"), status);
10661 result = 0;
10662 /*
10663 * Wait here instead of returning directly. This will block the
10664 * next connect command and allow processing of the disconnect
10665 * in SME else we might hit some race conditions leading to SME
10666 * and HDD out of sync. As disconnect is already in progress,
10667 * wait here for 1 sec instead of 5 sec.
10668 */
10669 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10670 goto wait_for_disconnect;
10671 }
10672 /*
10673 * Wait here instead of returning directly, this will block the next
10674 * connect command and allow processing of the scan for ssid and
10675 * the previous connect command in CSR. Else we might hit some
10676 * race conditions leading to SME and HDD out of sync.
10677 */
10678 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10679 {
10680 hddLog(LOG1,
10681 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10682 }
10683 else if ( 0 != status )
10684 {
10685 hddLog(LOGE,
10686 FL("csrRoamDisconnect failure, returned %d"),
10687 (int)status);
10688 result = -EINVAL;
10689 goto disconnected;
10690 }
10691wait_for_disconnect:
10692 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10693 msecs_to_jiffies(wait_time));
10694 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10695 {
10696 hddLog(LOGE,
10697 "%s: Failed to disconnect, timed out", __func__);
10698 result = -ETIMEDOUT;
10699 }
10700disconnected:
10701 hddLog(LOG1,
10702 FL("Set HDD connState to eConnectionState_NotConnected"));
10703 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10704#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10705 /* Sending disconnect event to userspace for kernel version < 3.11
10706 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10707 */
10708 hddLog(LOG1, FL("Send disconnected event to userspace"));
10709
10710 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10711 WLAN_REASON_UNSPECIFIED);
10712#endif
10713
10714 EXIT();
10715 return result;
10716}
10717
10718/*
10719 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10720 * on indoor channel
10721 * @hdd_ctx: pointer to hdd context
10722 *
10723 * STA should be disconnected before starting the SAP if it is on indoor
10724 * channel.
10725 *
10726 * Return: void
10727 */
10728void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10729{
10730
10731 hdd_adapter_t *sta_adapter;
10732 tANI_U8 sta_chan;
10733
10734 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10735
10736 if (!sta_chan) {
10737 hddLog(LOG1, FL("STA not connected"));
10738 return;
10739 }
10740
10741 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10742
10743 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10744 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10745 sta_chan);
10746 return;
10747 }
10748
10749 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10750
10751 if (!sta_adapter) {
10752 hddLog(LOG1, FL("STA adapter doesn't exist"));
10753 return;
10754 }
10755
10756 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10757 /* Issue Disconnect request */
10758 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10759}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010760
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010761int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10762{
10763 struct hdd_cache_channels *cache_chann;
10764 struct wiphy *wiphy;
10765 int freq, status, rfChannel;
10766 int i, band_num, channel_num;
10767 struct ieee80211_channel *wiphy_channel;
10768
10769 ENTER();
10770
10771 if (!hdd_ctx) {
10772 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10773 return -EINVAL;
10774 }
10775
10776 wiphy = hdd_ctx->wiphy;
10777
10778 mutex_lock(&hdd_ctx->cache_channel_lock);
10779
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010780 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010781
10782 if (!cache_chann || !cache_chann->num_channels) {
10783 hddLog(VOS_TRACE_LEVEL_INFO,
10784 "%s channel list is NULL or num channels are zero",
10785 __func__);
10786 mutex_unlock(&hdd_ctx->cache_channel_lock);
10787 return -EINVAL;
10788 }
10789
10790 for (i = 0; i < cache_chann->num_channels; i++) {
10791 status = hdd_wlan_get_freq(
10792 cache_chann->channel_info[i].channel_num,
10793 &freq);
10794
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010795 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10796 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010797 if (!wiphy->bands[band_num])
10798 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010799 for (channel_num = 0; channel_num <
10800 wiphy->bands[band_num]->n_channels;
10801 channel_num++) {
10802 wiphy_channel = &(wiphy->bands[band_num]->
10803 channels[channel_num]);
10804 if (wiphy_channel->center_freq == freq) {
10805 rfChannel = wiphy_channel->hw_value;
10806 /*
10807 *Restore the orginal states
10808 *of the channels
10809 */
10810 vos_nv_set_channel_state(
10811 rfChannel,
10812 cache_chann->
10813 channel_info[i].reg_status);
10814 wiphy_channel->flags =
10815 cache_chann->
10816 channel_info[i].wiphy_status;
10817 break;
10818 }
10819 }
10820 if (channel_num < wiphy->bands[band_num]->n_channels)
10821 break;
10822 }
10823 }
10824
10825 mutex_unlock(&hdd_ctx->cache_channel_lock);
10826
10827 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10828 if (status)
10829 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10830 EXIT();
10831
10832 return 0;
10833}
10834
10835/*
10836 * wlan_hdd_disable_channels() - Cache the the channels
10837 * and current state of the channels from the channel list
10838 * received in the command and disable the channels on the
10839 * wiphy and NV table.
10840 * @hdd_ctx: Pointer to hdd context
10841 *
10842 * @return: 0 on success, Error code on failure
10843 */
10844
10845static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10846{
10847 struct hdd_cache_channels *cache_chann;
10848 struct wiphy *wiphy;
10849 int freq, status, rfChannel;
10850 int i, band_num, band_ch_num;
10851 struct ieee80211_channel *wiphy_channel;
10852
10853 if (!hdd_ctx) {
10854 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10855 return -EINVAL;
10856 }
10857
10858 wiphy = hdd_ctx->wiphy;
10859
10860 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010861 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010862
10863 if (!cache_chann || !cache_chann->num_channels) {
10864 hddLog(VOS_TRACE_LEVEL_INFO,
10865 "%s channel list is NULL or num channels are zero",
10866 __func__);
10867 mutex_unlock(&hdd_ctx->cache_channel_lock);
10868 return -EINVAL;
10869 }
10870
10871 for (i = 0; i < cache_chann->num_channels; i++) {
10872 status = hdd_wlan_get_freq(
10873 cache_chann->channel_info[i].channel_num,
10874 &freq);
10875
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010876 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010877 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010878 if (!wiphy->bands[band_num])
10879 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010880 for (band_ch_num = 0; band_ch_num <
10881 wiphy->bands[band_num]->n_channels;
10882 band_ch_num++) {
10883 wiphy_channel = &(wiphy->bands[band_num]->
10884 channels[band_ch_num]);
10885 if (wiphy_channel->center_freq == freq) {
10886 rfChannel = wiphy_channel->hw_value;
10887 /*
10888 * Cache the current states of
10889 * the channels
10890 */
10891 cache_chann->
10892 channel_info[i].reg_status =
10893 vos_nv_getChannelEnabledState(
10894 rfChannel);
10895
10896 cache_chann->
10897 channel_info[i].wiphy_status =
10898 wiphy_channel->flags;
10899 hddLog(VOS_TRACE_LEVEL_INFO,
10900 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10901 cache_chann->
10902 channel_info[i].channel_num,
10903 cache_chann->
10904 channel_info[i].reg_status,
10905 wiphy_channel->flags);
10906
10907 vos_nv_set_channel_state(
10908 rfChannel,
10909 NV_CHANNEL_DISABLE);
10910 wiphy_channel->flags |=
10911 IEEE80211_CHAN_DISABLED;
10912 break;
10913 }
10914 }
10915 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10916 break;
10917 }
10918 }
10919
10920 mutex_unlock(&hdd_ctx->cache_channel_lock);
10921 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10922 return 0;
10923}
10924
Jeff Johnson295189b2012-06-20 16:38:30 -070010925#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10926static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10927 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010928#else
10929static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10930 struct cfg80211_beacon_data *params,
10931 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010932 enum nl80211_hidden_ssid hidden_ssid,
10933 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010935{
10936 tsap_Config_t *pConfig;
10937 beacon_data_t *pBeacon = NULL;
10938 struct ieee80211_mgmt *pMgmt_frame;
10939 v_U8_t *pIe=NULL;
10940 v_U16_t capab_info;
10941 eCsrAuthType RSNAuthType;
10942 eCsrEncryptionType RSNEncryptType;
10943 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010944 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 tpWLAN_SAPEventCB pSapEventCallback;
10946 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010948 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010950 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010952 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010953 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053010954 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010955 v_BOOL_t MFPCapable = VOS_FALSE;
10956 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010957 v_BOOL_t sapEnable11AC =
10958 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010959 u_int16_t prev_rsn_length = 0;
10960
Jeff Johnson295189b2012-06-20 16:38:30 -070010961 ENTER();
10962
Nitesh Shah9b066282017-06-06 18:05:52 +053010963 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010964
10965 /*
10966 * For STA+SAP concurrency support from GUI, first STA connection gets
10967 * triggered and while it is in progress, SAP start also comes up.
10968 * Once STA association is successful, STA connect event is sent to
10969 * kernel which gets queued in kernel workqueue and supplicant won't
10970 * process M1 received from AP and send M2 until this NL80211_CONNECT
10971 * event is received. Workqueue is not scheduled as RTNL lock is already
10972 * taken by hostapd thread which has issued start_bss command to driver.
10973 * Driver cannot complete start_bss as the pending command at the head
10974 * of the SME command pending list is hw_mode_update for STA session
10975 * which cannot be processed as SME is in WAITforKey state for STA
10976 * interface. The start_bss command for SAP interface is queued behind
10977 * the hw_mode_update command and so it cannot be processed until
10978 * hw_mode_update command is processed. This is causing a deadlock so
10979 * disconnect the STA interface first if connection or key exchange is
10980 * in progress and then start SAP interface.
10981 */
10982 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
10983 if (sta_adapter) {
10984 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
10985 sta_adapter->sessionId);
10986 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10987 }
10988
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010989 iniConfig = pHddCtx->cfg_ini;
10990
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010991 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053010992 if (iniConfig->disable_indoor_channel &&
10993 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010994 hdd_update_indoor_channel(pHddCtx, true);
10995
10996 if (!VOS_IS_STATUS_SUCCESS(
10997 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10998 hdd_update_indoor_channel(pHddCtx, false);
10999 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11000 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011001 ret = eHAL_STATUS_FAILURE;
11002 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011003 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011004
11005 /* check if STA is on indoor channel */
11006 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11007 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011008 }
11009
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011010 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11011 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11012 wlan_hdd_disable_channels(pHddCtx);
11013 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11014 }
11015
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11017
11018 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11019
11020 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11021
11022 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11023
11024 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11025
11026 //channel is already set in the set_channel Call back
11027 //pConfig->channel = pCommitConfig->channel;
11028
11029 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011030 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011031 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11032
11033 pConfig->dtim_period = pBeacon->dtim_period;
11034
Arif Hussain6d2a3322013-11-17 19:50:10 -080011035 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 pConfig->dtim_period);
11037
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011038 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011039 {
11040 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011042 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11043 {
11044 tANI_BOOLEAN restartNeeded;
11045 pConfig->ieee80211d = 1;
11046 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11047 sme_setRegInfo(hHal, pConfig->countryCode);
11048 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11049 }
11050 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011052 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011053 pConfig->ieee80211d = 1;
11054 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11055 sme_setRegInfo(hHal, pConfig->countryCode);
11056 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011058 else
11059 {
11060 pConfig->ieee80211d = 0;
11061 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011062 /*
11063 * If auto channel is configured i.e. channel is 0,
11064 * so skip channel validation.
11065 */
11066 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11067 {
11068 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11069 {
11070 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011071 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011072 ret = -EINVAL;
11073 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011074 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011075 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011076 }
11077 else
11078 {
11079 if(1 != pHddCtx->is_dynamic_channel_range_set)
11080 {
11081 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11082 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11083 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11084 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011085 pHddCtx->is_dynamic_channel_range_set = 0;
11086 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011087 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011088 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011089 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 {
11091 pConfig->ieee80211d = 0;
11092 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011093
11094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11095 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11096 pConfig->authType = eSAP_OPEN_SYSTEM;
11097 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11098 pConfig->authType = eSAP_SHARED_KEY;
11099 else
11100 pConfig->authType = eSAP_AUTO_SWITCH;
11101#else
11102 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11103 pConfig->authType = eSAP_OPEN_SYSTEM;
11104 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11105 pConfig->authType = eSAP_SHARED_KEY;
11106 else
11107 pConfig->authType = eSAP_AUTO_SWITCH;
11108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011109
11110 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011111
11112 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011114#ifdef SAP_AUTH_OFFLOAD
11115 /* In case of sap offload, hostapd.conf is configuted with open mode and
11116 * security is configured from ini file. Due to open mode in hostapd.conf
11117 * privacy bit is set to false which will result in not sending,
11118 * data packets as encrypted.
11119 * If enable_sap_auth_offload is enabled in ini and
11120 * sap_auth_offload_sec_type is type of WPA2-PSK,
11121 * driver will set privacy bit to 1.
11122 */
11123 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11124 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11125 pConfig->privacy = VOS_TRUE;
11126#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011127
11128 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11129
11130 /*Set wps station to configured*/
11131 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11132
11133 if(pIe)
11134 {
11135 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11136 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011137 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011138 ret = -EINVAL;
11139 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 }
11141 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11142 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011143 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 /* Check 15 bit of WPS IE as it contain information for wps state
11145 * WPS state
11146 */
11147 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11148 {
11149 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11150 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11151 {
11152 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11153 }
11154 }
11155 }
11156 else
11157 {
11158 pConfig->wps_state = SAP_WPS_DISABLED;
11159 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011161
c_hpothufe599e92014-06-16 11:38:55 +053011162 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11163 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11164 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11165 eCSR_ENCRYPT_TYPE_NONE;
11166
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011168 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 WLAN_EID_RSN);
11171 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011174 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11175 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11176 pConfig->RSNWPAReqIELength);
11177 else
11178 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11179 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011180 /* The actual processing may eventually be more extensive than
11181 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 * by the app.
11183 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011184 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11186 &RSNEncryptType,
11187 &mcRSNEncryptType,
11188 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011189 &MFPCapable,
11190 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011191 pConfig->RSNWPAReqIE[1]+2,
11192 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011193
11194 if( VOS_STATUS_SUCCESS == status )
11195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011196 /* Now copy over all the security attributes you have
11197 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 * */
11199 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11200 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11201 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11202 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011203 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011204 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11206 }
11207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011208
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11210 pBeacon->tail, pBeacon->tail_len);
11211
11212 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11213 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011214 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 {
11216 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011217 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011219 if (pConfig->RSNWPAReqIELength <=
11220 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11221 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11222 pIe[1] + 2);
11223 else
11224 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11225 pConfig->RSNWPAReqIELength);
11226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 }
11228 else
11229 {
11230 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011231 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11232 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11233 pConfig->RSNWPAReqIELength);
11234 else
11235 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11236 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011237 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11239 &RSNEncryptType,
11240 &mcRSNEncryptType,
11241 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011242 &MFPCapable,
11243 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011244 pConfig->RSNWPAReqIE[1]+2,
11245 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011246
11247 if( VOS_STATUS_SUCCESS == status )
11248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011249 /* Now copy over all the security attributes you have
11250 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 * */
11252 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11253 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11254 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11255 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011256 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011257 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11259 }
11260 }
11261 }
11262
Kapil Gupta137ef892016-12-13 19:38:00 +053011263 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011264 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011265 ret = -EINVAL;
11266 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011267 }
11268
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11270
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011271#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 if (params->ssid != NULL)
11273 {
11274 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11275 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11276 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11277 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11278 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011279#else
11280 if (ssid != NULL)
11281 {
11282 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11283 pConfig->SSIDinfo.ssid.length = ssid_len;
11284 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11285 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11286 }
11287#endif
11288
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011289 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011291
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 /* default value */
11293 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11294 pConfig->num_accept_mac = 0;
11295 pConfig->num_deny_mac = 0;
11296
11297 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11298 pBeacon->tail, pBeacon->tail_len);
11299
11300 /* pIe for black list is following form:
11301 type : 1 byte
11302 length : 1 byte
11303 OUI : 4 bytes
11304 acl type : 1 byte
11305 no of mac addr in black list: 1 byte
11306 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011307 */
11308 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 {
11310 pConfig->SapMacaddr_acl = pIe[6];
11311 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011312 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011313 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011314 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11315 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11317 for (i = 0; i < pConfig->num_deny_mac; i++)
11318 {
11319 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11320 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 }
11323 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11324 pBeacon->tail, pBeacon->tail_len);
11325
11326 /* pIe for white list is following form:
11327 type : 1 byte
11328 length : 1 byte
11329 OUI : 4 bytes
11330 acl type : 1 byte
11331 no of mac addr in white list: 1 byte
11332 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011333 */
11334 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
11336 pConfig->SapMacaddr_acl = pIe[6];
11337 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011338 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011340 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11341 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11343 for (i = 0; i < pConfig->num_accept_mac; i++)
11344 {
11345 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11346 acl_entry++;
11347 }
11348 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011349
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11351
Jeff Johnsone7245742012-09-05 17:12:55 -070011352#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011353 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011354 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11355 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011356 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11357 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011358 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11359 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011360 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11361 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011362 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011363 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011364 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011365 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011366
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011367 /* If ACS disable and selected channel <= 14
11368 * OR
11369 * ACS enabled and ACS operating band is choosen as 2.4
11370 * AND
11371 * VHT in 2.4G Disabled
11372 * THEN
11373 * Fallback to 11N mode
11374 */
11375 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11376 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011377 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011378 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011379 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011380 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11381 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011382 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11383 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011384 }
11385#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011386
Jeff Johnson295189b2012-06-20 16:38:30 -070011387 // ht_capab is not what the name conveys,this is used for protection bitmap
11388 pConfig->ht_capab =
11389 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11390
Kapil Gupta137ef892016-12-13 19:38:00 +053011391 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 {
11393 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011394 ret = -EINVAL;
11395 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 }
11397
11398 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11401 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011402 pConfig->obssProtEnabled =
11403 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011404
Chet Lanctot8cecea22014-02-11 19:09:36 -080011405#ifdef WLAN_FEATURE_11W
11406 pConfig->mfpCapable = MFPCapable;
11407 pConfig->mfpRequired = MFPRequired;
11408 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11409 pConfig->mfpCapable, pConfig->mfpRequired);
11410#endif
11411
Arif Hussain6d2a3322013-11-17 19:50:10 -080011412 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011414 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11415 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11416 (int)pConfig->channel);
11417 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11418 pConfig->SapHw_mode, pConfig->privacy,
11419 pConfig->authType);
11420 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11421 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11422 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11423 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011424
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011425 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 {
11427 //Bss already started. just return.
11428 //TODO Probably it should update some beacon params.
11429 hddLog( LOGE, "Bss Already started...Ignore the request");
11430 EXIT();
11431 return 0;
11432 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011433
Agarwal Ashish51325b52014-06-16 16:50:49 +053011434 if (vos_max_concurrent_connections_reached()) {
11435 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011436 ret = -EINVAL;
11437 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011438 }
11439
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 pConfig->persona = pHostapdAdapter->device_mode;
11441
Peng Xu2446a892014-09-05 17:21:18 +053011442 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11443 if ( NULL != psmeConfig)
11444 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011445 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011446 sme_GetConfigParam(hHal, psmeConfig);
11447 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011448#ifdef WLAN_FEATURE_AP_HT40_24G
11449 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11450 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11451 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11452 {
11453 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11454 sme_UpdateConfig (hHal, psmeConfig);
11455 }
11456#endif
Peng Xu2446a892014-09-05 17:21:18 +053011457 vos_mem_free(psmeConfig);
11458 }
Peng Xuafc34e32014-09-25 13:23:55 +053011459 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011460
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011461 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011463
11464 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11466 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11467 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011468 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011469 ret = -EINVAL;
11470 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 }
11472
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11475
11476 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011479 {
11480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011481 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011482 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 VOS_ASSERT(0);
11484 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011487 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11488 VOS_STATUS_SUCCESS)
11489 {
11490 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11491 VOS_ASSERT(0);
11492 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011493 /* Initialize WMM configuation */
11494 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011495 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011496
Anurag Chouhan83026002016-12-13 22:46:21 +053011497#ifdef DHCP_SERVER_OFFLOAD
11498 /* set dhcp server offload */
11499 if (iniConfig->enable_dhcp_srv_offload &&
11500 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011501 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011502 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011503 if (!VOS_IS_STATUS_SUCCESS(status))
11504 {
11505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11506 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011507 vos_event_reset(&pHostapdState->vosEvent);
11508 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11509 status = vos_wait_single_event(&pHostapdState->vosEvent,
11510 10000);
11511 if (!VOS_IS_STATUS_SUCCESS(status)) {
11512 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011513 ret = -EINVAL;
11514 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011515 }
11516 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011517 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011518 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11519 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11520 {
11521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11522 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11523 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011524 vos_event_reset(&pHostapdState->vosEvent);
11525 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11526 status = vos_wait_single_event(&pHostapdState->vosEvent,
11527 10000);
11528 if (!VOS_IS_STATUS_SUCCESS(status)) {
11529 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011530 ret = -EINVAL;
11531 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011532 }
11533 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011534 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011535#ifdef MDNS_OFFLOAD
11536 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011537 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011538 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11539 if (VOS_IS_STATUS_SUCCESS(status))
11540 {
11541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11542 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011543 vos_event_reset(&pHostapdState->vosEvent);
11544 if (VOS_STATUS_SUCCESS ==
11545 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11546 status = vos_wait_single_event(&pHostapdState->vosEvent,
11547 10000);
11548 if (!VOS_IS_STATUS_SUCCESS(status)) {
11549 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011550 ret = -EINVAL;
11551 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011552 }
11553 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011554 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011555 status = vos_wait_single_event(&pHostapdAdapter->
11556 mdns_status.vos_event, 2000);
11557 if (!VOS_IS_STATUS_SUCCESS(status) ||
11558 pHostapdAdapter->mdns_status.mdns_enable_status ||
11559 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11560 pHostapdAdapter->mdns_status.mdns_resp_status)
11561 {
11562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11563 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11564 pHostapdAdapter->mdns_status.mdns_enable_status,
11565 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11566 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011567 vos_event_reset(&pHostapdState->vosEvent);
11568 if (VOS_STATUS_SUCCESS ==
11569 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11570 status = vos_wait_single_event(&pHostapdState->vosEvent,
11571 10000);
11572 if (!VOS_IS_STATUS_SUCCESS(status)) {
11573 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011574 ret = -EINVAL;
11575 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011576 }
11577 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011578 }
11579 }
11580#endif /* MDNS_OFFLOAD */
11581 } else {
11582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11583 ("DHCP Disabled ini %d, FW %d"),
11584 iniConfig->enable_dhcp_srv_offload,
11585 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011586 }
11587#endif /* DHCP_SERVER_OFFLOAD */
11588
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011589#ifdef WLAN_FEATURE_P2P_DEBUG
11590 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11591 {
11592 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11593 {
11594 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11595 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011596 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011597 }
11598 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11599 {
11600 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11601 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011602 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011603 }
11604 }
11605#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011606 /* Check and restart SAP if it is on Unsafe channel */
11607 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011608
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 pHostapdState->bCommit = TRUE;
11610 EXIT();
11611
11612 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011613error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011614 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11615 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011616 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011617 if (iniConfig->disable_indoor_channel &&
11618 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011619 hdd_update_indoor_channel(pHddCtx, false);
11620 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11621 }
11622
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011623 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011624
11625tdls_enable:
11626 if (ret != eHAL_STATUS_SUCCESS)
11627 wlan_hdd_tdls_reenable(pHddCtx);
11628
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011629 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011630}
11631
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011632#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011633static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011634 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 struct beacon_parameters *params)
11636{
11637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011638 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011639 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011640
11641 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11644 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11645 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011646 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11647 hdd_device_modetoString(pAdapter->device_mode),
11648 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011649
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011650 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11651 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011652 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011653 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011654 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011655 }
11656
Agarwal Ashish51325b52014-06-16 16:50:49 +053011657 if (vos_max_concurrent_connections_reached()) {
11658 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11659 return -EINVAL;
11660 }
11661
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011662 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 )
11665 {
11666 beacon_data_t *old,*new;
11667
11668 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011669
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011671 {
11672 hddLog(VOS_TRACE_LEVEL_WARN,
11673 FL("already beacon info added to session(%d)"),
11674 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011677
11678 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11679
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011680 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 {
11682 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011683 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 return -EINVAL;
11685 }
11686
11687 pAdapter->sessionCtx.ap.beacon = new;
11688
11689 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11690 }
11691
11692 EXIT();
11693 return status;
11694}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011696static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11697 struct net_device *dev,
11698 struct beacon_parameters *params)
11699{
11700 int ret;
11701
11702 vos_ssr_protect(__func__);
11703 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11704 vos_ssr_unprotect(__func__);
11705
11706 return ret;
11707}
11708
11709static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 struct net_device *dev,
11711 struct beacon_parameters *params)
11712{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011714 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11715 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011716 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011717
11718 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011719
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011720 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11721 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11722 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11724 __func__, hdd_device_modetoString(pAdapter->device_mode),
11725 pAdapter->device_mode);
11726
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11728 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011729 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011730 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011731 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011732 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011733
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011734 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 {
11738 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011741
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011743 {
11744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11745 FL("session(%d) old and new heads points to NULL"),
11746 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011748 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011749
11750 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11751
11752 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011754 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 return -EINVAL;
11756 }
11757
11758 pAdapter->sessionCtx.ap.beacon = new;
11759
11760 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11761 }
11762
11763 EXIT();
11764 return status;
11765}
11766
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011767static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11768 struct net_device *dev,
11769 struct beacon_parameters *params)
11770{
11771 int ret;
11772
11773 vos_ssr_protect(__func__);
11774 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11775 vos_ssr_unprotect(__func__);
11776
11777 return ret;
11778}
11779
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011780#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11781
11782#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011783static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011785#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011786static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011787 struct net_device *dev)
11788#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011789{
11790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011791 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011792 hdd_context_t *pHddCtx = NULL;
11793 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011795 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011796
11797 ENTER();
11798
11799 if (NULL == pAdapter)
11800 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011802 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 return -ENODEV;
11804 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11807 TRACE_CODE_HDD_CFG80211_STOP_AP,
11808 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11810 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011812 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011814 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011815
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011816 pScanInfo = &pHddCtx->scan_info;
11817
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11819 __func__, hdd_device_modetoString(pAdapter->device_mode),
11820 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011821
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011822 /*
11823 * if a sta connection is in progress in another adapter, disconnect
11824 * the sta and complete the sap operation. sta will reconnect
11825 * after sap stop is done.
11826 */
11827 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11828 if (staAdapter) {
11829 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11830 staAdapter->sessionId);
11831 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11832 }
11833
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011834 ret = wlan_hdd_scan_abort(pAdapter);
11835
Girish Gowli4bf7a632014-06-12 13:42:11 +053011836 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011837 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11839 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011840
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011841 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011842 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11844 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011845
Jeff Johnsone7245742012-09-05 17:12:55 -070011846 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011847 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011848 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011849 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011850 }
11851
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011852 /* Delete all associated STAs before stopping AP/P2P GO */
11853 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011854 hdd_hostapd_stop(dev);
11855
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011857 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 )
11859 {
11860 beacon_data_t *old;
11861
11862 old = pAdapter->sessionCtx.ap.beacon;
11863
11864 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011865 {
11866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11867 FL("session(%d) beacon data points to NULL"),
11868 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011870 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011871
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011873
11874 mutex_lock(&pHddCtx->sap_lock);
11875 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11876 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011877 hdd_hostapd_state_t *pHostapdState =
11878 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11879
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011880 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11881 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011882 vos_event_reset(&pHostapdState->vosEvent);
11883
Jeff Johnson4416a782013-03-25 14:17:50 -070011884 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11887
11888 if (!VOS_IS_STATUS_SUCCESS(status))
11889 {
11890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011891 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011893 }
11894 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011895 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011896 /* BSS stopped, clear the active sessions for this device mode */
11897 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 }
11899 mutex_unlock(&pHddCtx->sap_lock);
11900
11901 if(status != VOS_STATUS_SUCCESS)
11902 {
11903 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011904 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 return -EINVAL;
11906 }
11907
Jeff Johnson4416a782013-03-25 14:17:50 -070011908 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11910 ==eHAL_STATUS_FAILURE)
11911 {
11912 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011913 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 }
11915
Jeff Johnson4416a782013-03-25 14:17:50 -070011916 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11918 eANI_BOOLEAN_FALSE) )
11919 {
11920 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011921 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 }
11923
11924 // Reset WNI_CFG_PROBE_RSP Flags
11925 wlan_hdd_reset_prob_rspies(pAdapter);
11926
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011927 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11928
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 pAdapter->sessionCtx.ap.beacon = NULL;
11930 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011931#ifdef WLAN_FEATURE_P2P_DEBUG
11932 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11933 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11934 {
11935 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11936 "GO got removed");
11937 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11938 }
11939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 }
11941 EXIT();
11942 return status;
11943}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011944
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011945#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11946static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11947 struct net_device *dev)
11948{
11949 int ret;
11950
11951 vos_ssr_protect(__func__);
11952 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11953 vos_ssr_unprotect(__func__);
11954
11955 return ret;
11956}
11957#else
11958static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11959 struct net_device *dev)
11960{
11961 int ret;
11962
11963 vos_ssr_protect(__func__);
11964 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11965 vos_ssr_unprotect(__func__);
11966
11967 return ret;
11968}
11969#endif
11970
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011971#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11972
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011973static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011974 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011975 struct cfg80211_ap_settings *params)
11976{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011977 hdd_adapter_t *pAdapter;
11978 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011979 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011980
11981 ENTER();
11982
Girish Gowlib143d7a2015-02-18 19:39:55 +053011983 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011986 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011987 return -ENODEV;
11988 }
11989
11990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11991 if (NULL == pAdapter)
11992 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011994 "%s: HDD adapter is Null", __func__);
11995 return -ENODEV;
11996 }
11997
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11999 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12000 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012001 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12002 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012004 "%s: HDD adapter magic is invalid", __func__);
12005 return -ENODEV;
12006 }
12007
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012008 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12009
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012010 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012011 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012012 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012013 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012014 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012015 }
12016
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012017 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12018 __func__, hdd_device_modetoString(pAdapter->device_mode),
12019 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012020
12021 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012022 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012023 )
12024 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012025 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012026
12027 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012028
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012029 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012030 {
12031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12032 FL("already beacon info added to session(%d)"),
12033 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012035 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012036
Girish Gowlib143d7a2015-02-18 19:39:55 +053012037#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12038 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12039 &new,
12040 &params->beacon);
12041#else
12042 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12043 &new,
12044 &params->beacon,
12045 params->dtim_period);
12046#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012047
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012048 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012049 {
12050 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012051 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012052 return -EINVAL;
12053 }
12054 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012056 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12057#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12058 params->channel, params->channel_type);
12059#else
12060 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12061#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012062#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012063 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012064 params->ssid_len, params->hidden_ssid,
12065 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012066 }
12067
12068 EXIT();
12069 return status;
12070}
12071
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012072static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12073 struct net_device *dev,
12074 struct cfg80211_ap_settings *params)
12075{
12076 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012077
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012078 vos_ssr_protect(__func__);
12079 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12080 vos_ssr_unprotect(__func__);
12081
12082 return ret;
12083}
12084
12085static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012086 struct net_device *dev,
12087 struct cfg80211_beacon_data *params)
12088{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012089 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012090 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012091 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012092
12093 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12096 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12097 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012099 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012100
12101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12102 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012103 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012105 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012106 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012107
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012108 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012109 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012110 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012111 {
12112 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012114 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012117 {
12118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12119 FL("session(%d) beacon data points to NULL"),
12120 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012121 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012122 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012123
12124 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12125
12126 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012127 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012128 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012129 return -EINVAL;
12130 }
12131
12132 pAdapter->sessionCtx.ap.beacon = new;
12133
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012134 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12135 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012136 }
12137
12138 EXIT();
12139 return status;
12140}
12141
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012142static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12143 struct net_device *dev,
12144 struct cfg80211_beacon_data *params)
12145{
12146 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012147
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012148 vos_ssr_protect(__func__);
12149 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12150 vos_ssr_unprotect(__func__);
12151
12152 return ret;
12153}
12154
12155#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012156
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012157static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 struct net_device *dev,
12159 struct bss_parameters *params)
12160{
12161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012162 hdd_context_t *pHddCtx;
12163 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012164
12165 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012166
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012167 if (NULL == pAdapter)
12168 {
12169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12170 "%s: HDD adapter is Null", __func__);
12171 return -ENODEV;
12172 }
12173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012174 ret = wlan_hdd_validate_context(pHddCtx);
12175 if (0 != ret)
12176 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012177 return ret;
12178 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12180 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12181 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12183 __func__, hdd_device_modetoString(pAdapter->device_mode),
12184 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012185
12186 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 {
12190 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12191 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012192 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 {
12194 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012195 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 }
12197
12198 EXIT();
12199 return 0;
12200}
12201
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012202static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12203 struct net_device *dev,
12204 struct bss_parameters *params)
12205{
12206 int ret;
12207
12208 vos_ssr_protect(__func__);
12209 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12210 vos_ssr_unprotect(__func__);
12211
12212 return ret;
12213}
Kiet Lam10841362013-11-01 11:36:50 +053012214/* FUNCTION: wlan_hdd_change_country_code_cd
12215* to wait for contry code completion
12216*/
12217void* wlan_hdd_change_country_code_cb(void *pAdapter)
12218{
12219 hdd_adapter_t *call_back_pAdapter = pAdapter;
12220 complete(&call_back_pAdapter->change_country_code);
12221 return NULL;
12222}
12223
Jeff Johnson295189b2012-06-20 16:38:30 -070012224/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012225 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12227 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012228int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 struct net_device *ndev,
12230 enum nl80211_iftype type,
12231 u32 *flags,
12232 struct vif_params *params
12233 )
12234{
12235 struct wireless_dev *wdev;
12236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012237 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012239 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012241 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 eMib_dot11DesiredBssType connectedBssType;
12243 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012244 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012245
12246 ENTER();
12247
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012248 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012249 {
12250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12251 "%s: Adapter context is null", __func__);
12252 return VOS_STATUS_E_FAILURE;
12253 }
12254
12255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12256 if (!pHddCtx)
12257 {
12258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12259 "%s: HDD context is null", __func__);
12260 return VOS_STATUS_E_FAILURE;
12261 }
12262
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12264 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12265 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012266 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012267 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012269 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 }
12271
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12273 __func__, hdd_device_modetoString(pAdapter->device_mode),
12274 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012275
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012276 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12277 hddLog(VOS_TRACE_LEVEL_FATAL,
12278 "%s: STA + MON is in progress, cannot change interface",
12279 __func__);
12280 }
12281
Agarwal Ashish51325b52014-06-16 16:50:49 +053012282 if (vos_max_concurrent_connections_reached()) {
12283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12284 return -EINVAL;
12285 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012286 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012287 wdev = ndev->ieee80211_ptr;
12288
12289#ifdef WLAN_BTAMP_FEATURE
12290 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12291 (NL80211_IFTYPE_ADHOC == type)||
12292 (NL80211_IFTYPE_AP == type)||
12293 (NL80211_IFTYPE_P2P_GO == type))
12294 {
12295 pHddCtx->isAmpAllowed = VOS_FALSE;
12296 // stop AMP traffic
12297 status = WLANBAP_StopAmp();
12298 if(VOS_STATUS_SUCCESS != status )
12299 {
12300 pHddCtx->isAmpAllowed = VOS_TRUE;
12301 hddLog(VOS_TRACE_LEVEL_FATAL,
12302 "%s: Failed to stop AMP", __func__);
12303 return -EINVAL;
12304 }
12305 }
12306#endif //WLAN_BTAMP_FEATURE
12307 /* Reset the current device mode bit mask*/
12308 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12309
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012310 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12311 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12312 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012313 {
12314 /* Notify Mode change in case of concurrency.
12315 * Below function invokes TDLS teardown Functionality Since TDLS is
12316 * not Supported in case of concurrency i.e Once P2P session
12317 * is detected disable offchannel and teardown TDLS links
12318 */
12319 hddLog(LOG1,
12320 FL("Device mode = %d Interface type = %d"),
12321 pAdapter->device_mode, type);
12322 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12323 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012324
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012327 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 )
12329 {
12330 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012331 if (!pWextState)
12332 {
12333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12334 "%s: pWextState is null", __func__);
12335 return VOS_STATUS_E_FAILURE;
12336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 pRoamProfile = &pWextState->roamProfile;
12338 LastBSSType = pRoamProfile->BSSType;
12339
12340 switch (type)
12341 {
12342 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 hddLog(VOS_TRACE_LEVEL_INFO,
12345 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12346 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012347#ifdef WLAN_FEATURE_11AC
12348 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12349 {
12350 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12351 }
12352#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012353 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012354 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012356 //Check for sub-string p2p to confirm its a p2p interface
12357 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012358 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012359#ifdef FEATURE_WLAN_TDLS
12360 mutex_lock(&pHddCtx->tdls_lock);
12361 wlan_hdd_tdls_exit(pAdapter, TRUE);
12362 mutex_unlock(&pHddCtx->tdls_lock);
12363#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012364 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12365 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12366 }
12367 else
12368 {
12369 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012370 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012371 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012373
Jeff Johnson295189b2012-06-20 16:38:30 -070012374 case NL80211_IFTYPE_ADHOC:
12375 hddLog(VOS_TRACE_LEVEL_INFO,
12376 "%s: setting interface Type to ADHOC", __func__);
12377 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12378 pRoamProfile->phyMode =
12379 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012380 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012382 hdd_set_ibss_ops( pAdapter );
12383 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012384
12385 status = hdd_sta_id_hash_attach(pAdapter);
12386 if (VOS_STATUS_SUCCESS != status) {
12387 hddLog(VOS_TRACE_LEVEL_ERROR,
12388 FL("Failed to initialize hash for IBSS"));
12389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 break;
12391
12392 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 {
12395 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12396 "%s: setting interface Type to %s", __func__,
12397 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12398
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012399 //Cancel any remain on channel for GO mode
12400 if (NL80211_IFTYPE_P2P_GO == type)
12401 {
12402 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12403 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012404 if (NL80211_IFTYPE_AP == type)
12405 {
12406 /*
12407 * As Loading WLAN Driver one interface being created
12408 * for p2p device address. This will take one HW STA and
12409 * the max number of clients that can connect to softAP
12410 * will be reduced by one. so while changing the interface
12411 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12412 * as it is not required in SoftAP mode.
12413 */
12414
12415 // Get P2P Adapter
12416 pP2pAdapter = hdd_get_adapter(pHddCtx,
12417 WLAN_HDD_P2P_DEVICE);
12418 if (pP2pAdapter)
12419 {
Min Liuf3481952018-12-10 16:01:14 +080012420 wlan_hdd_release_intf_addr(pHddCtx,
12421 pP2pAdapter->macAddressCurrent.bytes);
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012422 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12423 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12424 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12425 }
12426 }
12427
Swaroop Goltia2e32212014-04-09 23:37:33 +053012428 //Disable IMPS & BMPS for SAP/GO
12429 if(VOS_STATUS_E_FAILURE ==
12430 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12431 {
12432 //Fail to Exit BMPS
12433 VOS_ASSERT(0);
12434 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012435
12436 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12437
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012438#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012439
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012440 /* A Mutex Lock is introduced while changing the mode to
12441 * protect the concurrent access for the Adapters by TDLS
12442 * module.
12443 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012444 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012445#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012447 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012448 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012449 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12450 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012451#ifdef FEATURE_WLAN_TDLS
12452 mutex_unlock(&pHddCtx->tdls_lock);
12453#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012454 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12455 (pConfig->apRandomBssidEnabled))
12456 {
12457 /* To meet Android requirements create a randomized
12458 MAC address of the form 02:1A:11:Fx:xx:xx */
12459 get_random_bytes(&ndev->dev_addr[3], 3);
12460 ndev->dev_addr[0] = 0x02;
12461 ndev->dev_addr[1] = 0x1A;
12462 ndev->dev_addr[2] = 0x11;
12463 ndev->dev_addr[3] |= 0xF0;
12464 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12465 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012466 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12467 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012468 }
12469
Jeff Johnson295189b2012-06-20 16:38:30 -070012470 hdd_set_ap_ops( pAdapter->dev );
12471
Kiet Lam10841362013-11-01 11:36:50 +053012472 /* This is for only SAP mode where users can
12473 * control country through ini.
12474 * P2P GO follows station country code
12475 * acquired during the STA scanning. */
12476 if((NL80211_IFTYPE_AP == type) &&
12477 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12478 {
12479 int status = 0;
12480 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12481 "%s: setting country code from INI ", __func__);
12482 init_completion(&pAdapter->change_country_code);
12483 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12484 (void *)(tSmeChangeCountryCallback)
12485 wlan_hdd_change_country_code_cb,
12486 pConfig->apCntryCode, pAdapter,
12487 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012488 eSIR_FALSE,
12489 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012490 if (eHAL_STATUS_SUCCESS == status)
12491 {
12492 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012493 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012494 &pAdapter->change_country_code,
12495 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012496 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012497 {
12498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012499 FL("SME Timed out while setting country code %ld"),
12500 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012501
12502 if (pHddCtx->isLogpInProgress)
12503 {
12504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12505 "%s: LOGP in Progress. Ignore!!!", __func__);
12506 return -EAGAIN;
12507 }
Kiet Lam10841362013-11-01 11:36:50 +053012508 }
12509 }
12510 else
12511 {
12512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012513 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012514 return -EINVAL;
12515 }
12516 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012517 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 if(status != VOS_STATUS_SUCCESS)
12519 {
12520 hddLog(VOS_TRACE_LEVEL_FATAL,
12521 "%s: Error initializing the ap mode", __func__);
12522 return -EINVAL;
12523 }
12524 hdd_set_conparam(1);
12525
Nirav Shah7e3c8132015-06-22 23:51:42 +053012526 status = hdd_sta_id_hash_attach(pAdapter);
12527 if (VOS_STATUS_SUCCESS != status)
12528 {
12529 hddLog(VOS_TRACE_LEVEL_ERROR,
12530 FL("Failed to initialize hash for AP"));
12531 return -EINVAL;
12532 }
12533
Jeff Johnson295189b2012-06-20 16:38:30 -070012534 /*interface type changed update in wiphy structure*/
12535 if(wdev)
12536 {
12537 wdev->iftype = type;
12538 pHddCtx->change_iface = type;
12539 }
12540 else
12541 {
12542 hddLog(VOS_TRACE_LEVEL_ERROR,
12543 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12544 return -EINVAL;
12545 }
12546 goto done;
12547 }
12548
12549 default:
12550 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12551 __func__);
12552 return -EOPNOTSUPP;
12553 }
12554 }
12555 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 )
12558 {
12559 switch(type)
12560 {
12561 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012564
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012565 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12566 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12567 /*
12568 * The p2p interface was deleted while SoftAP mode was init,
12569 * create that interface now that the SoftAP is going down.
12570 */
12571 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12572 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12573 VOS_TRUE);
12574 }
12575
Deepthi Gowri500fc472014-08-11 19:53:10 +053012576 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012577
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012578#ifdef FEATURE_WLAN_TDLS
12579
12580 /* A Mutex Lock is introduced while changing the mode to
12581 * protect the concurrent access for the Adapters by TDLS
12582 * module.
12583 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012584 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012585#endif
c_hpothu002231a2015-02-05 14:58:51 +053012586 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012588 //Check for sub-string p2p to confirm its a p2p interface
12589 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012590 {
12591 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12592 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12593 }
12594 else
12595 {
12596 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012597 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012598 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012599
12600 /* set con_mode to STA only when no SAP concurrency mode */
12601 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12602 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12605 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012606#ifdef FEATURE_WLAN_TDLS
12607 mutex_unlock(&pHddCtx->tdls_lock);
12608#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012609 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 if( VOS_STATUS_SUCCESS != status )
12611 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012612 /* In case of JB, for P2P-GO, only change interface will be called,
12613 * This is the right place to enable back bmps_imps()
12614 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012615 if (pHddCtx->hdd_wlan_suspended)
12616 {
12617 hdd_set_pwrparams(pHddCtx);
12618 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012619 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 goto done;
12621 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12625 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 goto done;
12627 default:
12628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12629 __func__);
12630 return -EOPNOTSUPP;
12631
12632 }
12633
12634 }
12635 else
12636 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012637 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12638 __func__, hdd_device_modetoString(pAdapter->device_mode),
12639 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 return -EOPNOTSUPP;
12641 }
12642
12643
12644 if(pRoamProfile)
12645 {
12646 if ( LastBSSType != pRoamProfile->BSSType )
12647 {
12648 /*interface type changed update in wiphy structure*/
12649 wdev->iftype = type;
12650
12651 /*the BSS mode changed, We need to issue disconnect
12652 if connected or in IBSS disconnect state*/
12653 if ( hdd_connGetConnectedBssType(
12654 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12655 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12656 {
12657 /*need to issue a disconnect to CSR.*/
12658 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12659 if( eHAL_STATUS_SUCCESS ==
12660 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12661 pAdapter->sessionId,
12662 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12663 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012664 ret = wait_for_completion_interruptible_timeout(
12665 &pAdapter->disconnect_comp_var,
12666 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12667 if (ret <= 0)
12668 {
12669 hddLog(VOS_TRACE_LEVEL_ERROR,
12670 FL("wait on disconnect_comp_var failed %ld"), ret);
12671 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012672 }
12673 }
12674 }
12675 }
12676
12677done:
12678 /*set bitmask based on updated value*/
12679 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012680
12681 /* Only STA mode support TM now
12682 * all other mode, TM feature should be disabled */
12683 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12684 (~VOS_STA & pHddCtx->concurrency_mode) )
12685 {
12686 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12687 }
12688
Jeff Johnson295189b2012-06-20 16:38:30 -070012689#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012690 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012691 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012692 {
12693 //we are ok to do AMP
12694 pHddCtx->isAmpAllowed = VOS_TRUE;
12695 }
12696#endif //WLAN_BTAMP_FEATURE
12697 EXIT();
12698 return 0;
12699}
12700
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012701/*
12702 * FUNCTION: wlan_hdd_cfg80211_change_iface
12703 * wrapper function to protect the actual implementation from SSR.
12704 */
12705int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12706 struct net_device *ndev,
12707 enum nl80211_iftype type,
12708 u32 *flags,
12709 struct vif_params *params
12710 )
12711{
12712 int ret;
12713
12714 vos_ssr_protect(__func__);
12715 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12716 vos_ssr_unprotect(__func__);
12717
12718 return ret;
12719}
12720
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012721#ifdef FEATURE_WLAN_TDLS
12722static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012723 struct net_device *dev,
12724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12725 const u8 *mac,
12726#else
12727 u8 *mac,
12728#endif
12729 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012730{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012732 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012733 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012734 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012735 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012736 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012737
12738 ENTER();
12739
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012740 if (!dev) {
12741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12742 return -EINVAL;
12743 }
12744
12745 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12746 if (!pAdapter) {
12747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12748 return -EINVAL;
12749 }
12750
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012751 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012752 {
12753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12754 "Invalid arguments");
12755 return -EINVAL;
12756 }
Hoonki Lee27511902013-03-14 18:19:06 -070012757
12758 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12759 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12760 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012762 "%s: TDLS mode is disabled OR not enabled in FW."
12763 MAC_ADDRESS_STR " Request declined.",
12764 __func__, MAC_ADDR_ARRAY(mac));
12765 return -ENOTSUPP;
12766 }
12767
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012768 if (pHddCtx->isLogpInProgress)
12769 {
12770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12771 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012772 wlan_hdd_tdls_set_link_status(pAdapter,
12773 mac,
12774 eTDLS_LINK_IDLE,
12775 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012776 return -EBUSY;
12777 }
12778
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012779 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012780 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012781
12782 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012784 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12785 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012786 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012787 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012788 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012789
12790 /* in add station, we accept existing valid staId if there is */
12791 if ((0 == update) &&
12792 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12793 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012794 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012796 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012797 " link_status %d. staId %d. add station ignored.",
12798 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012799 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012800 return 0;
12801 }
12802 /* in change station, we accept only when staId is valid */
12803 if ((1 == update) &&
12804 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12805 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12806 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012807 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012809 "%s: " MAC_ADDRESS_STR
12810 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012811 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12812 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12813 mutex_unlock(&pHddCtx->tdls_lock);
12814 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012815 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012816 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012817
12818 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012819 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012820 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12822 "%s: " MAC_ADDRESS_STR
12823 " TDLS setup is ongoing. Request declined.",
12824 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012825 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012826 }
12827
12828 /* first to check if we reached to maximum supported TDLS peer.
12829 TODO: for now, return -EPERM looks working fine,
12830 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012831 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12832 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012833 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12835 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012836 " TDLS Max peer already connected. Request declined."
12837 " Num of peers (%d), Max allowed (%d).",
12838 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12839 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012840 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012841 }
12842 else
12843 {
12844 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012845 mutex_lock(&pHddCtx->tdls_lock);
12846 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012847 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012848 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012849 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12851 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12852 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012853 return -EPERM;
12854 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012855 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012856 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012857 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012858 wlan_hdd_tdls_set_link_status(pAdapter,
12859 mac,
12860 eTDLS_LINK_CONNECTING,
12861 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012862
Jeff Johnsond75fe012013-04-06 10:53:06 -070012863 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012864 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012865 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012867 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012868 if(StaParams->htcap_present)
12869 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012871 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012873 "ht_capa->extended_capabilities: %0x",
12874 StaParams->HTCap.extendedHtCapInfo);
12875 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012877 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012879 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012880 if(StaParams->vhtcap_present)
12881 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012883 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12884 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12885 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12886 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012887 {
12888 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012890 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012892 "[%d]: %x ", i, StaParams->supported_rates[i]);
12893 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012894 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012895 else if ((1 == update) && (NULL == StaParams))
12896 {
12897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12898 "%s : update is true, but staParams is NULL. Error!", __func__);
12899 return -EPERM;
12900 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012901
12902 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12903
12904 if (!update)
12905 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012906 /*Before adding sta make sure that device exited from BMPS*/
12907 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12908 {
12909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12910 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12911 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12912 if (status != VOS_STATUS_SUCCESS) {
12913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12914 }
12915 }
12916
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012917 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012918 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012919 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012920 hddLog(VOS_TRACE_LEVEL_ERROR,
12921 FL("Failed to add TDLS peer STA. Enable Bmps"));
12922 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012923 return -EPERM;
12924 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012925 }
12926 else
12927 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012928 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012929 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012930 if (ret != eHAL_STATUS_SUCCESS) {
12931 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12932 return -EPERM;
12933 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012934 }
12935
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012936 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012937 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12938
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012939 mutex_lock(&pHddCtx->tdls_lock);
12940 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12941
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012942 if ((pTdlsPeer != NULL) &&
12943 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012944 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012945 hddLog(VOS_TRACE_LEVEL_ERROR,
12946 FL("peer link status %u"), pTdlsPeer->link_status);
12947 mutex_unlock(&pHddCtx->tdls_lock);
12948 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012949 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012950 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012951
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012952 if (ret <= 0)
12953 {
12954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12955 "%s: timeout waiting for tdls add station indication %ld",
12956 __func__, ret);
12957 goto error;
12958 }
12959
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012960 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12961 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012963 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012964 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012965 }
12966
12967 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012968
12969error:
Atul Mittal115287b2014-07-08 13:26:33 +053012970 wlan_hdd_tdls_set_link_status(pAdapter,
12971 mac,
12972 eTDLS_LINK_IDLE,
12973 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012974 return -EPERM;
12975
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012976}
12977#endif
12978
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012979VOS_STATUS wlan_hdd_send_sta_authorized_event(
12980 hdd_adapter_t *adapter,
12981 hdd_context_t *hdd_ctx,
12982 const v_MACADDR_t *mac_addr)
12983{
12984 struct sk_buff *vendor_event;
12985 uint32_t sta_flags = 0;
12986 VOS_STATUS status;
12987
12988 ENTER();
12989
12990 if (!hdd_ctx) {
12991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12992 return -EINVAL;
12993 }
12994
12995 vendor_event =
12996 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053012997 hdd_ctx->wiphy,
12998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12999 &adapter->wdev,
13000#endif
13001 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013002 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13003 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13004 GFP_KERNEL);
13005 if (!vendor_event) {
13006 hddLog(VOS_TRACE_LEVEL_ERROR,
13007 FL("cfg80211_vendor_event_alloc failed"));
13008 return -EINVAL;
13009 }
13010
13011 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13012
13013 status = nla_put_u32(vendor_event,
13014 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13015 sta_flags);
13016 if (status) {
13017 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13018 kfree_skb(vendor_event);
13019 return VOS_STATUS_E_FAILURE;
13020 }
13021 status = nla_put(vendor_event,
13022 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13023 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13024 if (status) {
13025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13026 kfree_skb(vendor_event);
13027 return VOS_STATUS_E_FAILURE;
13028 }
13029
13030 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13031
13032 EXIT();
13033 return 0;
13034}
13035
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013036static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013037 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13039 const u8 *mac,
13040#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013043 struct station_parameters *params)
13044{
13045 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013046 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013047 hdd_context_t *pHddCtx;
13048 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013049 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013050 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013051#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013052 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013053 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013054 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013055 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013056#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013057
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013058 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013059
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013060 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013061 if ((NULL == pAdapter))
13062 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013064 "invalid adapter ");
13065 return -EINVAL;
13066 }
13067
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013068 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13069 TRACE_CODE_HDD_CHANGE_STATION,
13070 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013072
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013073 ret = wlan_hdd_validate_context(pHddCtx);
13074 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013075 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013076 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013077 }
13078
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013079 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13080
13081 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013082 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13084 "invalid HDD station context");
13085 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013086 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013087 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13088
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013089 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13090 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013092 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013094 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 WLANTL_STA_AUTHENTICATED);
13096
Gopichand Nakkala29149562013-05-10 21:43:41 +053013097 if (status != VOS_STATUS_SUCCESS)
13098 {
13099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13100 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13101 return -EINVAL;
13102 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013103 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13104 &STAMacAddress);
13105 if (status != VOS_STATUS_SUCCESS)
13106 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 }
13108 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013109 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13110 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013111#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013112 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13113 StaParams.capability = params->capability;
13114 StaParams.uapsd_queues = params->uapsd_queues;
13115 StaParams.max_sp = params->max_sp;
13116
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013117 /* Convert (first channel , number of channels) tuple to
13118 * the total list of channels. This goes with the assumption
13119 * that if the first channel is < 14, then the next channels
13120 * are an incremental of 1 else an incremental of 4 till the number
13121 * of channels.
13122 */
13123 if (0 != params->supported_channels_len) {
13124 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013125 for ( i = 0 ; i < params->supported_channels_len
13126 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013127 {
13128 int wifi_chan_index;
13129 StaParams.supported_channels[j] = params->supported_channels[i];
13130 wifi_chan_index =
13131 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13132 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013133 for(k=1; k <= no_of_channels
13134 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013135 {
13136 StaParams.supported_channels[j+1] =
13137 StaParams.supported_channels[j] + wifi_chan_index;
13138 j+=1;
13139 }
13140 }
13141 StaParams.supported_channels_len = j;
13142 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013143 if (params->supported_oper_classes_len >
13144 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13146 "received oper classes:%d, resetting it to max supported %d",
13147 params->supported_oper_classes_len,
13148 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13149 params->supported_oper_classes_len =
13150 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13151 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013152 vos_mem_copy(StaParams.supported_oper_classes,
13153 params->supported_oper_classes,
13154 params->supported_oper_classes_len);
13155 StaParams.supported_oper_classes_len =
13156 params->supported_oper_classes_len;
13157
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013158 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13160 "received extn capabilities:%d, resetting it to max supported",
13161 params->ext_capab_len);
13162 params->ext_capab_len = sizeof(StaParams.extn_capability);
13163 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013164 if (0 != params->ext_capab_len)
13165 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013166 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013167
13168 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013169 {
13170 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013171 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013172 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013173
13174 StaParams.supported_rates_len = params->supported_rates_len;
13175
13176 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13177 * The supported_rates array , for all the structures propogating till Add Sta
13178 * to the firmware has to be modified , if the supplicant (ieee80211) is
13179 * modified to send more rates.
13180 */
13181
13182 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13183 */
13184 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13185 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13186
13187 if (0 != StaParams.supported_rates_len) {
13188 int i = 0;
13189 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13190 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013192 "Supported Rates with Length %d", StaParams.supported_rates_len);
13193 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013195 "[%d]: %0x", i, StaParams.supported_rates[i]);
13196 }
13197
13198 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013199 {
13200 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013201 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013202 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013203
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013204 if (0 != params->ext_capab_len ) {
13205 /*Define A Macro : TODO Sunil*/
13206 if ((1<<4) & StaParams.extn_capability[3]) {
13207 isBufSta = 1;
13208 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013209 /* TDLS Channel Switching Support */
13210 if ((1<<6) & StaParams.extn_capability[3]) {
13211 isOffChannelSupported = 1;
13212 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013213 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013214
13215 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013216 (params->ht_capa || params->vht_capa ||
13217 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013218 /* TDLS Peer is WME/QoS capable */
13219 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013220
13221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13222 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13223 __func__, isQosWmmSta, StaParams.htcap_present);
13224
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013225 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13226 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013227 isOffChannelSupported,
13228 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013229
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013230 if (VOS_STATUS_SUCCESS != status) {
13231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13232 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13233 return -EINVAL;
13234 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013235 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13236
13237 if (VOS_STATUS_SUCCESS != status) {
13238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13239 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13240 return -EINVAL;
13241 }
13242 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013243#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013244 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013245 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 return status;
13247}
13248
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13250static int wlan_hdd_change_station(struct wiphy *wiphy,
13251 struct net_device *dev,
13252 const u8 *mac,
13253 struct station_parameters *params)
13254#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013255static int wlan_hdd_change_station(struct wiphy *wiphy,
13256 struct net_device *dev,
13257 u8 *mac,
13258 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013259#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013260{
13261 int ret;
13262
13263 vos_ssr_protect(__func__);
13264 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13265 vos_ssr_unprotect(__func__);
13266
13267 return ret;
13268}
13269
Jeff Johnson295189b2012-06-20 16:38:30 -070013270/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013271 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013272 * This function is used to initialize the key information
13273 */
13274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013275static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013276 struct net_device *ndev,
13277 u8 key_index, bool pairwise,
13278 const u8 *mac_addr,
13279 struct key_params *params
13280 )
13281#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013282static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013283 struct net_device *ndev,
13284 u8 key_index, const u8 *mac_addr,
13285 struct key_params *params
13286 )
13287#endif
13288{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013289 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013290 tCsrRoamSetKey setKey;
13291 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013292 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013293 v_U32_t roamId= 0xFF;
13294 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013295 hdd_hostapd_state_t *pHostapdState;
13296 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013297 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013298 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013299 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013300 v_MACADDR_t *peerMacAddr;
13301 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013302 uint8_t staid = HDD_MAX_STA_COUNT;
13303 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013304
13305 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013306
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013307 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13308 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13309 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013310 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13311 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013312 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013314 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013315 }
13316
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013317 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13318 __func__, hdd_device_modetoString(pAdapter->device_mode),
13319 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013320
13321 if (CSR_MAX_NUM_KEY <= key_index)
13322 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013324 key_index);
13325
13326 return -EINVAL;
13327 }
13328
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013329 if (CSR_MAX_KEY_LEN < params->key_len)
13330 {
13331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13332 params->key_len);
13333
13334 return -EINVAL;
13335 }
13336
Jingxiang Gec438aea2017-10-26 16:44:00 +080013337 if (CSR_MAX_RSC_LEN < params->seq_len)
13338 {
13339 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13340 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013341
13342 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013343 }
13344
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013345 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013346 "%s: called with key index = %d & key length %d & seq length %d",
13347 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013348
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013349 peerMacAddr = (v_MACADDR_t *)mac_addr;
13350
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 /*extract key idx, key len and key*/
13352 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13353 setKey.keyId = key_index;
13354 setKey.keyLength = params->key_len;
13355 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013356 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013357
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013358 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 {
13360 case WLAN_CIPHER_SUITE_WEP40:
13361 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13362 break;
13363
13364 case WLAN_CIPHER_SUITE_WEP104:
13365 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13366 break;
13367
13368 case WLAN_CIPHER_SUITE_TKIP:
13369 {
13370 u8 *pKey = &setKey.Key[0];
13371 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13372
13373 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13374
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013375 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013376
13377 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013378 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013379 |--------------|----------|----------|
13380 <---16bytes---><--8bytes--><--8bytes-->
13381
13382 */
13383 /*Sme expects the 32 bytes key to be in the below order
13384
13385 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013386 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 |--------------|----------|----------|
13388 <---16bytes---><--8bytes--><--8bytes-->
13389 */
13390 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013391 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013392
13393 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013394 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013395
13396 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013397 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013398
13399
13400 break;
13401 }
13402
13403 case WLAN_CIPHER_SUITE_CCMP:
13404 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13405 break;
13406
13407#ifdef FEATURE_WLAN_WAPI
13408 case WLAN_CIPHER_SUITE_SMS4:
13409 {
13410 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13411 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13412 params->key, params->key_len);
13413 return 0;
13414 }
13415#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013416
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013417#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013418 case WLAN_CIPHER_SUITE_KRK:
13419 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13420 break;
13421#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013422
13423#ifdef WLAN_FEATURE_11W
13424 case WLAN_CIPHER_SUITE_AES_CMAC:
13425 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013426 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013427#endif
13428
Jeff Johnson295189b2012-06-20 16:38:30 -070013429 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013431 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013432 status = -EOPNOTSUPP;
13433 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013434 }
13435
13436 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13437 __func__, setKey.encType);
13438
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013439 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13441 (!pairwise)
13442#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013443 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013444#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013445 )
13446 {
13447 /* set group key*/
13448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13449 "%s- %d: setting Broadcast key",
13450 __func__, __LINE__);
13451 setKey.keyDirection = eSIR_RX_ONLY;
13452 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13453 }
13454 else
13455 {
13456 /* set pairwise key*/
13457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13458 "%s- %d: setting pairwise key",
13459 __func__, __LINE__);
13460 setKey.keyDirection = eSIR_TX_RX;
13461 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013462 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013463 }
13464 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13465 {
13466 setKey.keyDirection = eSIR_TX_RX;
13467 /*Set the group key*/
13468 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13469 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013470
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013471 if ( 0 != status )
13472 {
13473 hddLog(VOS_TRACE_LEVEL_ERROR,
13474 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013475 status = -EINVAL;
13476 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013477 }
13478 /*Save the keys here and call sme_RoamSetKey for setting
13479 the PTK after peer joins the IBSS network*/
13480 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13481 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013482 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013483 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013484 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13485 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13486 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013488 if( pHostapdState->bssState == BSS_START )
13489 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013490 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13491 vos_status = wlan_hdd_check_ula_done(pAdapter);
13492
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013493 if (peerMacAddr && (pairwise_set_key == true))
13494 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013495
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013496 if ( vos_status != VOS_STATUS_SUCCESS )
13497 {
13498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13499 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13500 __LINE__, vos_status );
13501
13502 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13503
13504 status = -EINVAL;
13505 goto end;
13506 }
13507
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13509
13510 if ( status != eHAL_STATUS_SUCCESS )
13511 {
13512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13513 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13514 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013515 status = -EINVAL;
13516 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013517 }
13518 }
13519
13520 /* Saving WEP keys */
13521 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13522 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13523 {
13524 //Save the wep key in ap context. Issue setkey after the BSS is started.
13525 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13526 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13527 }
13528 else
13529 {
13530 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013531 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13533 }
13534 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013535 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13536 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 {
13538 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13539 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13540
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13542 if (!pairwise)
13543#else
13544 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13545#endif
13546 {
13547 /* set group key*/
13548 if (pHddStaCtx->roam_info.deferKeyComplete)
13549 {
13550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13551 "%s- %d: Perform Set key Complete",
13552 __func__, __LINE__);
13553 hdd_PerformRoamSetKeyComplete(pAdapter);
13554 }
13555 }
13556
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013557 if (pairwise_set_key == true)
13558 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013559
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13561
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013562 pWextState->roamProfile.Keys.defaultIndex = key_index;
13563
13564
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013565 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 params->key, params->key_len);
13567
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013568
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13570
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013571 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013572 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573 __func__, setKey.peerMac[0], setKey.peerMac[1],
13574 setKey.peerMac[2], setKey.peerMac[3],
13575 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 setKey.keyDirection);
13577
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013578 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013579
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013580 if ( vos_status != VOS_STATUS_SUCCESS )
13581 {
13582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13584 __LINE__, vos_status );
13585
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013586 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013587
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013588 status = -EINVAL;
13589 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013590
13591 }
13592
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013593#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013594 /* The supplicant may attempt to set the PTK once pre-authentication
13595 is done. Save the key in the UMAC and include it in the ADD BSS
13596 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013597 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013598 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013599 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013600 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13601 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013602 status = 0;
13603 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013604 }
13605 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13606 {
13607 hddLog(VOS_TRACE_LEVEL_ERROR,
13608 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013609 status = -EINVAL;
13610 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013611 }
13612#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013613
13614 /* issue set key request to SME*/
13615 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13616 pAdapter->sessionId, &setKey, &roamId );
13617
13618 if ( 0 != status )
13619 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013620 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013621 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13622 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013623 status = -EINVAL;
13624 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 }
13626
13627
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013628 /* in case of IBSS as there was no information available about WEP keys during
13629 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013630 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013631 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13632 !( ( IW_AUTH_KEY_MGMT_802_1X
13633 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13635 )
13636 &&
13637 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13638 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13639 )
13640 )
13641 {
13642 setKey.keyDirection = eSIR_RX_ONLY;
13643 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13644
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013647 __func__, setKey.peerMac[0], setKey.peerMac[1],
13648 setKey.peerMac[2], setKey.peerMac[3],
13649 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 setKey.keyDirection);
13651
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013652 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 pAdapter->sessionId, &setKey, &roamId );
13654
13655 if ( 0 != status )
13656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013657 hddLog(VOS_TRACE_LEVEL_ERROR,
13658 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 __func__, status);
13660 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013661 status = -EINVAL;
13662 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 }
13664 }
13665 }
13666
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013667 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013668 for (i = 0; i < params->seq_len; i++) {
13669 rsc_counter |= (params->seq[i] << i*8);
13670 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013671 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13672 }
13673
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013674end:
13675 /* Need to clear any trace of key value in the memory.
13676 * Thus zero out the memory even though it is local
13677 * variable.
13678 */
13679 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013680 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013681 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013682}
13683
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13685static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13686 struct net_device *ndev,
13687 u8 key_index, bool pairwise,
13688 const u8 *mac_addr,
13689 struct key_params *params
13690 )
13691#else
13692static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13693 struct net_device *ndev,
13694 u8 key_index, const u8 *mac_addr,
13695 struct key_params *params
13696 )
13697#endif
13698{
13699 int ret;
13700 vos_ssr_protect(__func__);
13701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13702 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13703 mac_addr, params);
13704#else
13705 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13706 params);
13707#endif
13708 vos_ssr_unprotect(__func__);
13709
13710 return ret;
13711}
13712
Jeff Johnson295189b2012-06-20 16:38:30 -070013713/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013714 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 * This function is used to get the key information
13716 */
13717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013718static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013721 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013722 const u8 *mac_addr, void *cookie,
13723 void (*callback)(void *cookie, struct key_params*)
13724 )
13725#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013726static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013727 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013728 struct net_device *ndev,
13729 u8 key_index, const u8 *mac_addr, void *cookie,
13730 void (*callback)(void *cookie, struct key_params*)
13731 )
13732#endif
13733{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013735 hdd_wext_state_t *pWextState = NULL;
13736 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013737 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013738 hdd_context_t *pHddCtx;
13739 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013740
13741 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013742
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013743 if (NULL == pAdapter)
13744 {
13745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13746 "%s: HDD adapter is Null", __func__);
13747 return -ENODEV;
13748 }
13749
13750 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13751 ret = wlan_hdd_validate_context(pHddCtx);
13752 if (0 != ret)
13753 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013754 return ret;
13755 }
13756
13757 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13758 pRoamProfile = &(pWextState->roamProfile);
13759
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13761 __func__, hdd_device_modetoString(pAdapter->device_mode),
13762 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013763
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 memset(&params, 0, sizeof(params));
13765
13766 if (CSR_MAX_NUM_KEY <= key_index)
13767 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013770 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013771
13772 switch(pRoamProfile->EncryptionType.encryptionType[0])
13773 {
13774 case eCSR_ENCRYPT_TYPE_NONE:
13775 params.cipher = IW_AUTH_CIPHER_NONE;
13776 break;
13777
13778 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13779 case eCSR_ENCRYPT_TYPE_WEP40:
13780 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13781 break;
13782
13783 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13784 case eCSR_ENCRYPT_TYPE_WEP104:
13785 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13786 break;
13787
13788 case eCSR_ENCRYPT_TYPE_TKIP:
13789 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13790 break;
13791
13792 case eCSR_ENCRYPT_TYPE_AES:
13793 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13794 break;
13795
13796 default:
13797 params.cipher = IW_AUTH_CIPHER_NONE;
13798 break;
13799 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013800
c_hpothuaaf19692014-05-17 17:01:48 +053013801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13802 TRACE_CODE_HDD_CFG80211_GET_KEY,
13803 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013804
Jeff Johnson295189b2012-06-20 16:38:30 -070013805 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13806 params.seq_len = 0;
13807 params.seq = NULL;
13808 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13809 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013810 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 return 0;
13812}
13813
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013814#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13815static int wlan_hdd_cfg80211_get_key(
13816 struct wiphy *wiphy,
13817 struct net_device *ndev,
13818 u8 key_index, bool pairwise,
13819 const u8 *mac_addr, void *cookie,
13820 void (*callback)(void *cookie, struct key_params*)
13821 )
13822#else
13823static int wlan_hdd_cfg80211_get_key(
13824 struct wiphy *wiphy,
13825 struct net_device *ndev,
13826 u8 key_index, const u8 *mac_addr, void *cookie,
13827 void (*callback)(void *cookie, struct key_params*)
13828 )
13829#endif
13830{
13831 int ret;
13832
13833 vos_ssr_protect(__func__);
13834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13835 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13836 mac_addr, cookie, callback);
13837#else
13838 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13839 callback);
13840#endif
13841 vos_ssr_unprotect(__func__);
13842
13843 return ret;
13844}
13845
Jeff Johnson295189b2012-06-20 16:38:30 -070013846/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013847 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 * This function is used to delete the key information
13849 */
13850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013851static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013853 u8 key_index,
13854 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 const u8 *mac_addr
13856 )
13857#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013858static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 struct net_device *ndev,
13860 u8 key_index,
13861 const u8 *mac_addr
13862 )
13863#endif
13864{
13865 int status = 0;
13866
13867 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 //it is observed that this is invalidating peer
13870 //key index whenever re-key is done. This is affecting data link.
13871 //It should be ok to ignore del_key.
13872#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13874 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13876 tCsrRoamSetKey setKey;
13877 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 ENTER();
13880
13881 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13882 __func__,pAdapter->device_mode);
13883
13884 if (CSR_MAX_NUM_KEY <= key_index)
13885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013886 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013887 key_index);
13888
13889 return -EINVAL;
13890 }
13891
13892 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13893 setKey.keyId = key_index;
13894
13895 if (mac_addr)
13896 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13897 else
13898 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13899
13900 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13901
13902 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013903 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013904 )
13905 {
13906
13907 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13909 if( pHostapdState->bssState == BSS_START)
13910 {
13911 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013912
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 if ( status != eHAL_STATUS_SUCCESS )
13914 {
13915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13916 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13917 __LINE__, status );
13918 }
13919 }
13920 }
13921 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013922 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013923 )
13924 {
13925 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13926
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013927 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13928
13929 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931 __func__, setKey.peerMac[0], setKey.peerMac[1],
13932 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013934 if(pAdapter->sessionCtx.station.conn_info.connState ==
13935 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013937 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 if ( 0 != status )
13941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013942 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 "%s: sme_RoamSetKey failure, returned %d",
13944 __func__, status);
13945 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13946 return -EINVAL;
13947 }
13948 }
13949 }
13950#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013951 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 return status;
13953}
13954
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13956static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13957 struct net_device *ndev,
13958 u8 key_index,
13959 bool pairwise,
13960 const u8 *mac_addr
13961 )
13962#else
13963static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13964 struct net_device *ndev,
13965 u8 key_index,
13966 const u8 *mac_addr
13967 )
13968#endif
13969{
13970 int ret;
13971
13972 vos_ssr_protect(__func__);
13973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13974 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13975 mac_addr);
13976#else
13977 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13978#endif
13979 vos_ssr_unprotect(__func__);
13980
13981 return ret;
13982}
13983
Jeff Johnson295189b2012-06-20 16:38:30 -070013984/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013985 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 * This function is used to set the default tx key index
13987 */
13988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013989static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 struct net_device *ndev,
13991 u8 key_index,
13992 bool unicast, bool multicast)
13993#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013994static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 struct net_device *ndev,
13996 u8 key_index)
13997#endif
13998{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013999 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014000 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014001 hdd_wext_state_t *pWextState;
14002 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014003 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014004
14005 ENTER();
14006
Gopichand Nakkala29149562013-05-10 21:43:41 +053014007 if ((NULL == pAdapter))
14008 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014010 "invalid adapter");
14011 return -EINVAL;
14012 }
14013
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14015 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14016 pAdapter->sessionId, key_index));
14017
Gopichand Nakkala29149562013-05-10 21:43:41 +053014018 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14019 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14020
14021 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14022 {
14023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14024 "invalid Wext state or HDD context");
14025 return -EINVAL;
14026 }
14027
Arif Hussain6d2a3322013-11-17 19:50:10 -080014028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014030
Jeff Johnson295189b2012-06-20 16:38:30 -070014031 if (CSR_MAX_NUM_KEY <= key_index)
14032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014033 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 key_index);
14035
14036 return -EINVAL;
14037 }
14038
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14040 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014041 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014043 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014045
Jeff Johnson295189b2012-06-20 16:38:30 -070014046 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014048 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014050 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014051 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014052#ifdef FEATURE_WLAN_WAPI
14053 (eCSR_ENCRYPT_TYPE_WPI !=
14054 pHddStaCtx->conn_info.ucEncryptionType) &&
14055#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014056 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014057 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014058 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014059 {
14060 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014062
Jeff Johnson295189b2012-06-20 16:38:30 -070014063 tCsrRoamSetKey setKey;
14064 v_U32_t roamId= 0xFF;
14065 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014066
14067 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014069
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 Keys->defaultIndex = (u8)key_index;
14071 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14072 setKey.keyId = key_index;
14073 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014074
14075 vos_mem_copy(&setKey.Key[0],
14076 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078
Gopichand Nakkala29149562013-05-10 21:43:41 +053014079 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014080
14081 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 &pHddStaCtx->conn_info.bssId[0],
14083 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014084
Gopichand Nakkala29149562013-05-10 21:43:41 +053014085 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14086 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14087 eCSR_ENCRYPT_TYPE_WEP104)
14088 {
14089 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14090 even though ap is configured for WEP-40 encryption. In this canse the key length
14091 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14092 type(104) and switching encryption type to 40*/
14093 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14094 eCSR_ENCRYPT_TYPE_WEP40;
14095 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14096 eCSR_ENCRYPT_TYPE_WEP40;
14097 }
14098
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014099 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014101
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014103 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014105
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 if ( 0 != status )
14107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108 hddLog(VOS_TRACE_LEVEL_ERROR,
14109 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014110 status);
14111 return -EINVAL;
14112 }
14113 }
14114 }
14115
14116 /* In SoftAp mode setting key direction for default mode */
14117 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14118 {
14119 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14120 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14121 (eCSR_ENCRYPT_TYPE_AES !=
14122 pWextState->roamProfile.EncryptionType.encryptionType[0])
14123 )
14124 {
14125 /* Saving key direction for default key index to TX default */
14126 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14127 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14128 }
14129 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014130 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 return status;
14132}
14133
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014134#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14135static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14136 struct net_device *ndev,
14137 u8 key_index,
14138 bool unicast, bool multicast)
14139#else
14140static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14141 struct net_device *ndev,
14142 u8 key_index)
14143#endif
14144{
14145 int ret;
14146 vos_ssr_protect(__func__);
14147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14148 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14149 multicast);
14150#else
14151 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14152#endif
14153 vos_ssr_unprotect(__func__);
14154
14155 return ret;
14156}
14157
Jeff Johnson295189b2012-06-20 16:38:30 -070014158/*
14159 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14160 * This function is used to inform the BSS details to nl80211 interface.
14161 */
14162static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14163 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14164{
14165 struct net_device *dev = pAdapter->dev;
14166 struct wireless_dev *wdev = dev->ieee80211_ptr;
14167 struct wiphy *wiphy = wdev->wiphy;
14168 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14169 int chan_no;
14170 int ie_length;
14171 const char *ie;
14172 unsigned int freq;
14173 struct ieee80211_channel *chan;
14174 int rssi = 0;
14175 struct cfg80211_bss *bss = NULL;
14176
Jeff Johnson295189b2012-06-20 16:38:30 -070014177 if( NULL == pBssDesc )
14178 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014179 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014180 return bss;
14181 }
14182
14183 chan_no = pBssDesc->channelId;
14184 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14185 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14186
14187 if( NULL == ie )
14188 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014189 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014190 return bss;
14191 }
14192
14193#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14194 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14195 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014196 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014197 }
14198 else
14199 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014200 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014201 }
14202#else
14203 freq = ieee80211_channel_to_frequency(chan_no);
14204#endif
14205
14206 chan = __ieee80211_get_channel(wiphy, freq);
14207
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014208 if (!chan) {
14209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14210 return NULL;
14211 }
14212
Abhishek Singhaee43942014-06-16 18:55:47 +053014213 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014214
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014215 return cfg80211_inform_bss(wiphy, chan,
14216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14217 CFG80211_BSS_FTYPE_UNKNOWN,
14218#endif
14219 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014220 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014221 pBssDesc->capabilityInfo,
14222 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014223 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014224}
14225
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014226/*
14227 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14228 * interface that BSS might have been lost.
14229 * @pAdapter: adaptor
14230 * @bssid: bssid which might have been lost
14231 *
14232 * Return: bss which is unlinked from kernel cache
14233 */
14234struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14235 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14236{
14237 struct net_device *dev = pAdapter->dev;
14238 struct wireless_dev *wdev = dev->ieee80211_ptr;
14239 struct wiphy *wiphy = wdev->wiphy;
14240 struct cfg80211_bss *bss = NULL;
14241
Abhishek Singh5a597e62016-12-05 15:16:30 +053014242 bss = hdd_get_bss_entry(wiphy,
14243 NULL, bssid,
14244 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014245 if (bss == NULL) {
14246 hddLog(LOGE, FL("BSS not present"));
14247 } else {
14248 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14249 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14250 cfg80211_unlink_bss(wiphy, bss);
14251 }
14252 return bss;
14253}
Jeff Johnson295189b2012-06-20 16:38:30 -070014254
14255
14256/*
14257 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14258 * This function is used to inform the BSS details to nl80211 interface.
14259 */
14260struct cfg80211_bss*
14261wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14262 tSirBssDescription *bss_desc
14263 )
14264{
14265 /*
14266 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14267 already exists in bss data base of cfg80211 for that particular BSS ID.
14268 Using cfg80211_inform_bss_frame to update the bss entry instead of
14269 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14270 now there is no possibility to get the mgmt(probe response) frame from PE,
14271 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14272 cfg80211_inform_bss_frame.
14273 */
14274 struct net_device *dev = pAdapter->dev;
14275 struct wireless_dev *wdev = dev->ieee80211_ptr;
14276 struct wiphy *wiphy = wdev->wiphy;
14277 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014278#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14279 qcom_ie_age *qie_age = NULL;
14280 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14281#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014283#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014284 const char *ie =
14285 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14286 unsigned int freq;
14287 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014288 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014290 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14291 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014292 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014293 hdd_context_t *pHddCtx;
14294 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014295#ifdef WLAN_OPEN_SOURCE
14296 struct timespec ts;
14297#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014298
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014299
Wilson Yangf80a0542013-10-07 13:02:37 -070014300 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14301 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014302 if (0 != status)
14303 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014304 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014305 }
14306
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014307 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014308 if (!mgmt)
14309 {
14310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14311 "%s: memory allocation failed ", __func__);
14312 return NULL;
14313 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014314
Jeff Johnson295189b2012-06-20 16:38:30 -070014315 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014316
14317#ifdef WLAN_OPEN_SOURCE
14318 /* Android does not want the timestamp from the frame.
14319 Instead it wants a monotonic increasing value */
14320 get_monotonic_boottime(&ts);
14321 mgmt->u.probe_resp.timestamp =
14322 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14323#else
14324 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014325 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14326 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014327
14328#endif
14329
Jeff Johnson295189b2012-06-20 16:38:30 -070014330 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14331 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014332
14333#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14334 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14335 /* Assuming this is the last IE, copy at the end */
14336 ie_length -=sizeof(qcom_ie_age);
14337 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14338 qie_age->element_id = QCOM_VENDOR_IE_ID;
14339 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14340 qie_age->oui_1 = QCOM_OUI1;
14341 qie_age->oui_2 = QCOM_OUI2;
14342 qie_age->oui_3 = QCOM_OUI3;
14343 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014344 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14345 * bss related timestamp is in units of ms. Due to this when scan results
14346 * are sent to lowi the scan age is high.To address this, send age in units
14347 * of 1/10 ms.
14348 */
14349 qie_age->age = (vos_timer_get_system_time() -
14350 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014351#endif
14352
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014354 if (bss_desc->fProbeRsp)
14355 {
14356 mgmt->frame_control |=
14357 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14358 }
14359 else
14360 {
14361 mgmt->frame_control |=
14362 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14363 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014364
14365#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014366 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014367 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014368 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014369 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014370 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014371 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014372 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014373
14374 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014375 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 }
14377 else
14378 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14380 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 kfree(mgmt);
14382 return NULL;
14383 }
14384#else
14385 freq = ieee80211_channel_to_frequency(chan_no);
14386#endif
14387 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014388 /*when the band is changed on the fly using the GUI, three things are done
14389 * 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)
14390 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14391 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14392 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14393 * and discards the channels correponding to previous band and calls back with zero bss results.
14394 * 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
14395 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14396 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14397 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14398 * So drop the bss and continue to next bss.
14399 */
14400 if(chan == NULL)
14401 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014402 hddLog(VOS_TRACE_LEVEL_ERROR,
14403 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14404 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014405 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014406 return NULL;
14407 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014408 /*To keep the rssi icon of the connected AP in the scan window
14409 *and the rssi icon of the wireless networks in sync
14410 * */
14411 if (( eConnectionState_Associated ==
14412 pAdapter->sessionCtx.station.conn_info.connState ) &&
14413 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14414 pAdapter->sessionCtx.station.conn_info.bssId,
14415 WNI_CFG_BSSID_LEN)) &&
14416 (pHddCtx->hdd_wlan_suspended == FALSE))
14417 {
14418 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14419 rssi = (pAdapter->rssi * 100);
14420 }
14421 else
14422 {
14423 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014425
Nirav Shah20ac06f2013-12-12 18:14:06 +053014426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014427 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14428 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014429
Jeff Johnson295189b2012-06-20 16:38:30 -070014430 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14431 frame_len, rssi, GFP_KERNEL);
14432 kfree(mgmt);
14433 return bss_status;
14434}
14435
14436/*
14437 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14438 * This function is used to update the BSS data base of CFG8011
14439 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014440struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 tCsrRoamInfo *pRoamInfo
14442 )
14443{
14444 tCsrRoamConnectedProfile roamProfile;
14445 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14446 struct cfg80211_bss *bss = NULL;
14447
14448 ENTER();
14449
14450 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14451 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14452
14453 if (NULL != roamProfile.pBssDesc)
14454 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014455 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14456 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014457
14458 if (NULL == bss)
14459 {
14460 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14461 __func__);
14462 }
14463
14464 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14465 }
14466 else
14467 {
14468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14469 __func__);
14470 }
14471 return bss;
14472}
14473
14474/*
14475 * FUNCTION: wlan_hdd_cfg80211_update_bss
14476 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014477static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14478 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014479 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014480{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014481 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014482 tCsrScanResultInfo *pScanResult;
14483 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014484 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014485 tScanResultHandle pResult;
14486 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014487 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014488 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014489 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014490
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14492 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14493 NO_SESSION, pAdapter->sessionId));
14494
Wilson Yangf80a0542013-10-07 13:02:37 -070014495 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014496 ret = wlan_hdd_validate_context(pHddCtx);
14497 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014498 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014499 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014500 }
14501
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014502 if (pAdapter->request != NULL)
14503 {
14504 if ((pAdapter->request->n_ssids == 1)
14505 && (pAdapter->request->ssids != NULL)
14506 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14507 is_p2p_scan = true;
14508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014509 /*
14510 * start getting scan results and populate cgf80211 BSS database
14511 */
14512 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14513
14514 /* no scan results */
14515 if (NULL == pResult)
14516 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14518 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014519 wlan_hdd_get_frame_logs(pAdapter,
14520 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 return status;
14522 }
14523
14524 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14525
14526 while (pScanResult)
14527 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014528 /*
14529 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14530 * entry already exists in bss data base of cfg80211 for that
14531 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14532 * bss entry instead of cfg80211_inform_bss, But this call expects
14533 * mgmt packet as input. As of now there is no possibility to get
14534 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014535 * ieee80211_mgmt(probe response) and passing to c
14536 * fg80211_inform_bss_frame.
14537 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014538 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14539 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14540 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014541 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14542 continue; //Skip the non p2p bss entries
14543 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014544 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14545 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014546
Jeff Johnson295189b2012-06-20 16:38:30 -070014547
14548 if (NULL == bss_status)
14549 {
14550 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014551 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014552 }
14553 else
14554 {
Yue Maf49ba872013-08-19 12:04:25 -070014555 cfg80211_put_bss(
14556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14557 wiphy,
14558#endif
14559 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014560 }
14561
14562 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14563 }
14564
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014565 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014566 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014567 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014568}
14569
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014570void
14571hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14572{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014573 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014574 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014575} /****** end hddPrintMacAddr() ******/
14576
14577void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014578hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014579{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014580 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014581 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014582 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14583 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14584 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014585} /****** end hddPrintPmkId() ******/
14586
14587//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14588//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14589
14590//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14591//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14592
14593#define dump_bssid(bssid) \
14594 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014595 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14596 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014597 }
14598
14599#define dump_pmkid(pMac, pmkid) \
14600 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014601 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14602 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014603 }
14604
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014605#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014606/*
14607 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14608 * This function is used to notify the supplicant of a new PMKSA candidate.
14609 */
14610int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014611 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014612 int index, bool preauth )
14613{
Jeff Johnsone7245742012-09-05 17:12:55 -070014614#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014615 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014616 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014617
14618 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014619 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014620
14621 if( NULL == pRoamInfo )
14622 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014623 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014624 return -EINVAL;
14625 }
14626
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014627 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14628 {
14629 dump_bssid(pRoamInfo->bssid);
14630 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014631 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014632 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014633#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014634 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014635}
14636#endif //FEATURE_WLAN_LFR
14637
Yue Maef608272013-04-08 23:09:17 -070014638#ifdef FEATURE_WLAN_LFR_METRICS
14639/*
14640 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14641 * 802.11r/LFR metrics reporting function to report preauth initiation
14642 *
14643 */
14644#define MAX_LFR_METRICS_EVENT_LENGTH 100
14645VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14646 tCsrRoamInfo *pRoamInfo)
14647{
14648 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14649 union iwreq_data wrqu;
14650
14651 ENTER();
14652
14653 if (NULL == pAdapter)
14654 {
14655 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14656 return VOS_STATUS_E_FAILURE;
14657 }
14658
14659 /* create the event */
14660 memset(&wrqu, 0, sizeof(wrqu));
14661 memset(metrics_notification, 0, sizeof(metrics_notification));
14662
14663 wrqu.data.pointer = metrics_notification;
14664 wrqu.data.length = scnprintf(metrics_notification,
14665 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14666 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14667
14668 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14669
14670 EXIT();
14671
14672 return VOS_STATUS_SUCCESS;
14673}
14674
14675/*
14676 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14677 * 802.11r/LFR metrics reporting function to report preauth completion
14678 * or failure
14679 */
14680VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14681 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14682{
14683 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14684 union iwreq_data wrqu;
14685
14686 ENTER();
14687
14688 if (NULL == pAdapter)
14689 {
14690 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14691 return VOS_STATUS_E_FAILURE;
14692 }
14693
14694 /* create the event */
14695 memset(&wrqu, 0, sizeof(wrqu));
14696 memset(metrics_notification, 0, sizeof(metrics_notification));
14697
14698 scnprintf(metrics_notification, sizeof(metrics_notification),
14699 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14700 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14701
14702 if (1 == preauth_status)
14703 strncat(metrics_notification, " TRUE", 5);
14704 else
14705 strncat(metrics_notification, " FALSE", 6);
14706
14707 wrqu.data.pointer = metrics_notification;
14708 wrqu.data.length = strlen(metrics_notification);
14709
14710 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14711
14712 EXIT();
14713
14714 return VOS_STATUS_SUCCESS;
14715}
14716
14717/*
14718 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14719 * 802.11r/LFR metrics reporting function to report handover initiation
14720 *
14721 */
14722VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14723 tCsrRoamInfo *pRoamInfo)
14724{
14725 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14726 union iwreq_data wrqu;
14727
14728 ENTER();
14729
14730 if (NULL == pAdapter)
14731 {
14732 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14733 return VOS_STATUS_E_FAILURE;
14734 }
14735
14736 /* create the event */
14737 memset(&wrqu, 0, sizeof(wrqu));
14738 memset(metrics_notification, 0, sizeof(metrics_notification));
14739
14740 wrqu.data.pointer = metrics_notification;
14741 wrqu.data.length = scnprintf(metrics_notification,
14742 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14743 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14744
14745 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14746
14747 EXIT();
14748
14749 return VOS_STATUS_SUCCESS;
14750}
14751#endif
14752
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014753
14754/**
14755 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14756 * @scan_req: scan request to be checked
14757 *
14758 * Return: true or false
14759 */
14760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14761static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14762 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014763 *scan_req, hdd_context_t
14764 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014765{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014766 if (!scan_req || !scan_req->wiphy ||
14767 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014768 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14769 return false;
14770 }
14771 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14772 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14773 return false;
14774 }
14775 return true;
14776}
14777#else
14778static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14779 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014780 *scan_req, hdd_context_t
14781 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014782{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014783 if (!scan_req || !scan_req->wiphy ||
14784 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014785 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14786 return false;
14787 }
14788 return true;
14789}
14790#endif
14791
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014792#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14793/**
14794 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14795 * @adapter: Pointer to the adapter
14796 * @req : Scan request
14797 * @aborted : true scan aborted false scan success
14798 *
14799 * This function notifies scan done to cfg80211
14800 *
14801 * Return: none
14802 */
14803static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14804 struct cfg80211_scan_request *req,
14805 bool aborted)
14806{
14807 struct cfg80211_scan_info info = {
14808 .aborted = aborted
14809 };
14810
14811 if (adapter->dev->flags & IFF_UP)
14812 cfg80211_scan_done(req, &info);
14813 else
14814 hddLog(LOGW,
14815 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14816}
14817#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14818/**
14819 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14820 * @adapter: Pointer to the adapter
14821 * @req : Scan request
14822 * @aborted : true scan aborted false scan success
14823 *
14824 * This function notifies scan done to cfg80211
14825 *
14826 * Return: none
14827 */
14828static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14829 struct cfg80211_scan_request *req,
14830 bool aborted)
14831{
14832 if (adapter->dev->flags & IFF_UP)
14833 cfg80211_scan_done(req, aborted);
14834 else
14835 hddLog(LOGW,
14836 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14837}
14838#else
14839/**
14840 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14841 * @adapter: Pointer to the adapter
14842 * @req : Scan request
14843 * @aborted : true scan aborted false scan success
14844 *
14845 * This function notifies scan done to cfg80211
14846 *
14847 * Return: none
14848 */
14849static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14850 struct cfg80211_scan_request *req,
14851 bool aborted)
14852{
14853 cfg80211_scan_done(req, aborted);
14854}
14855#endif
14856
Mukul Sharmab392b642017-08-17 17:45:29 +053014857#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014858/*
14859 * FUNCTION: hdd_cfg80211_scan_done_callback
14860 * scanning callback function, called after finishing scan
14861 *
14862 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014863static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014864 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14865{
14866 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014867 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014868 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014869 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 struct cfg80211_scan_request *req = NULL;
14871 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014872 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014873 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014874 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014875
14876 ENTER();
14877
c_manjee1b4ab9a2016-10-26 11:36:55 +053014878 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14879 !pAdapter->dev) {
14880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14881 return 0;
14882 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014883 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014884 if (NULL == pHddCtx) {
14885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014886 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014887 }
14888
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014889#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014890 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014891 {
14892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014893 }
14894#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014895 pScanInfo = &pHddCtx->scan_info;
14896
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014898 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014899 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014900 __func__, halHandle, pContext, (int) scanId, (int) status);
14901
Kiet Lamac06e2c2013-10-23 16:25:07 +053014902 pScanInfo->mScanPendingCounter = 0;
14903
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014905 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014906 &pScanInfo->scan_req_completion_event,
14907 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014908 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014910 hddLog(VOS_TRACE_LEVEL_ERROR,
14911 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014913 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014914 }
14915
Yue Maef608272013-04-08 23:09:17 -070014916 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 {
14918 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014919 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014920 }
14921
14922 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014923 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 {
14925 hddLog(VOS_TRACE_LEVEL_INFO,
14926 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014927 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 (int) scanId);
14929 }
14930
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014931#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014932 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014933#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014934 {
14935 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14936 pAdapter);
14937 if (0 > ret)
14938 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014940
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 /* If any client wait scan result through WEXT
14942 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014943 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 {
14945 /* The other scan request waiting for current scan finish
14946 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014947 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014949 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 }
14951 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014952 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 {
14954 struct net_device *dev = pAdapter->dev;
14955 union iwreq_data wrqu;
14956 int we_event;
14957 char *msg;
14958
14959 memset(&wrqu, '\0', sizeof(wrqu));
14960 we_event = SIOCGIWSCAN;
14961 msg = NULL;
14962 wireless_send_event(dev, we_event, &wrqu, msg);
14963 }
14964 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014965 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014966
14967 /* Get the Scan Req */
14968 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014969 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014970
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014971 /* Scan is no longer pending */
14972 pScanInfo->mScanPending = VOS_FALSE;
14973
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014974 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014978 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014979#endif
14980
14981 if (pAdapter->dev) {
14982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14983 pAdapter->dev->name);
14984 }
mukul sharmae7041822015-12-03 15:09:21 +053014985 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014986 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014987 }
14988
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014989 /* last_scan_timestamp is used to decide if new scan
14990 * is needed or not on station interface. If last station
14991 * scan time and new station scan time is less then
14992 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014993 * Also only last_scan_timestamp is updated here last_scan_channellist
14994 * is updated on receiving scan request itself to make sure kernel
14995 * allocated scan request(scan_req) object is not dereferenced here,
14996 * because interface down, where kernel frees scan_req, may happen any
14997 * time while driver is processing scan_done_callback. So it's better
14998 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014999 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015000 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15001 if (status == eCSR_SCAN_SUCCESS)
15002 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15003 else {
15004 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15005 sizeof(pHddCtx->scan_info.last_scan_channelList));
15006 pHddCtx->scan_info.last_scan_numChannels = 0;
15007 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015008 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015009 }
15010
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015011 /*
15012 * cfg80211_scan_done informing NL80211 about completion
15013 * of scanning
15014 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015015 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15016 {
15017 aborted = true;
15018 }
mukul sharmae7041822015-12-03 15:09:21 +053015019
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015021 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15022 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015023#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015024 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015025
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015026 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015027
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015028allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015029 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15030 ) && (pHddCtx->spoofMacAddr.isEnabled
15031 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015032 /* Generate new random mac addr for next scan */
15033 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015034
15035 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15036 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015037 }
15038
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015039 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015040 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015041
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015042 /* Acquire wakelock to handle the case where APP's tries to suspend
15043 * immediatly after the driver gets connect request(i.e after scan)
15044 * from supplicant, this result in app's is suspending and not able
15045 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015046 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015047
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015049 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015050#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015051#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015052 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015053#endif
15054
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 EXIT();
15056 return 0;
15057}
15058
15059/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015060 * FUNCTION: hdd_isConnectionInProgress
15061 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015062 *
15063 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015064v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15065 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015066{
15067 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15068 hdd_station_ctx_t *pHddStaCtx = NULL;
15069 hdd_adapter_t *pAdapter = NULL;
15070 VOS_STATUS status = 0;
15071 v_U8_t staId = 0;
15072 v_U8_t *staMac = NULL;
15073
15074 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15075
15076 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15077 {
15078 pAdapter = pAdapterNode->pAdapter;
15079
15080 if( pAdapter )
15081 {
15082 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015083 "%s: Adapter with device mode %s (%d) exists",
15084 __func__, hdd_device_modetoString(pAdapter->device_mode),
15085 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015086 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015087 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15088 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15089 (eConnectionState_Connecting ==
15090 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15091 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015092 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015093 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015094 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015095 if (session_id && reason)
15096 {
15097 *session_id = pAdapter->sessionId;
15098 *reason = eHDD_CONNECTION_IN_PROGRESS;
15099 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015100 return VOS_TRUE;
15101 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015102 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015103 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015104 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015105 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015106 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015107 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015108 if (session_id && reason)
15109 {
15110 *session_id = pAdapter->sessionId;
15111 *reason = eHDD_REASSOC_IN_PROGRESS;
15112 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015113 return VOS_TRUE;
15114 }
15115 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015116 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15117 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015118 {
15119 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15120 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015121 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15122 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015123 {
15124 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015125 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015126 "%s: client " MAC_ADDRESS_STR
15127 " is in the middle of WPS/EAPOL exchange.", __func__,
15128 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015129 if (session_id && reason)
15130 {
15131 *session_id = pAdapter->sessionId;
15132 *reason = eHDD_EAPOL_IN_PROGRESS;
15133 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015134 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015135 }
15136 }
15137 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15138 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15139 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015140 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15141 ptSapContext pSapCtx = NULL;
15142 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15143 if(pSapCtx == NULL){
15144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15145 FL("psapCtx is NULL"));
15146 return VOS_FALSE;
15147 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015148 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15149 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015150 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15151 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015152 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015153 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015154
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015155 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015156 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15157 "middle of WPS/EAPOL exchange.", __func__,
15158 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015159 if (session_id && reason)
15160 {
15161 *session_id = pAdapter->sessionId;
15162 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15163 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015164 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015165 }
15166 }
15167 }
15168 }
15169 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15170 pAdapterNode = pNext;
15171 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015172 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015173}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015174
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015175/**
15176 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15177 * to the Scan request
15178 * @scanRequest: Pointer to the csr scan request
15179 * @request: Pointer to the scan request from supplicant
15180 *
15181 * Return: None
15182 */
15183#ifdef CFG80211_SCAN_BSSID
15184static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15185 struct cfg80211_scan_request *request)
15186{
15187 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15188}
15189#else
15190static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15191 struct cfg80211_scan_request *request)
15192{
15193}
15194#endif
15195
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015196/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015197 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015198 * this scan respond to scan trigger and update cfg80211 scan database
15199 * later, scan dump command can be used to recieve scan results
15200 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015201int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015202#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15203 struct net_device *dev,
15204#endif
15205 struct cfg80211_scan_request *request)
15206{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015207 hdd_adapter_t *pAdapter = NULL;
15208 hdd_context_t *pHddCtx = NULL;
15209 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015210 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015211 tCsrScanRequest scanRequest;
15212 tANI_U8 *channelList = NULL, i;
15213 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015214 int status;
15215 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015217 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015218 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015219 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015220 v_U8_t curr_session_id;
15221 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015222
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015223#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15224 struct net_device *dev = NULL;
15225 if (NULL == request)
15226 {
15227 hddLog(VOS_TRACE_LEVEL_ERROR,
15228 "%s: scan req param null", __func__);
15229 return -EINVAL;
15230 }
15231 dev = request->wdev->netdev;
15232#endif
15233
15234 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15235 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15236 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15237
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 ENTER();
15239
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015240 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15241 __func__, hdd_device_modetoString(pAdapter->device_mode),
15242 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015243
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015244 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015245 if (0 != status)
15246 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015247 return status;
15248 }
15249
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015250 if (NULL == pwextBuf)
15251 {
15252 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15253 __func__);
15254 return -EIO;
15255 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015256 cfg_param = pHddCtx->cfg_ini;
15257 pScanInfo = &pHddCtx->scan_info;
15258
Jeff Johnson295189b2012-06-20 16:38:30 -070015259#ifdef WLAN_BTAMP_FEATURE
15260 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015261 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015263 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015264 "%s: No scanning when AMP is on", __func__);
15265 return -EOPNOTSUPP;
15266 }
15267#endif
15268 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015269 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015270 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015271 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015272 "%s: Not scanning on device_mode = %s (%d)",
15273 __func__, hdd_device_modetoString(pAdapter->device_mode),
15274 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 return -EOPNOTSUPP;
15276 }
15277
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015278 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15279 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15280 return -EOPNOTSUPP;
15281 }
15282
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 if (TRUE == pScanInfo->mScanPending)
15284 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015285 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15286 {
15287 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15288 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015289 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 }
15291
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015292 // Don't allow scan if PNO scan is going on.
15293 if (pHddCtx->isPnoEnable)
15294 {
15295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15296 FL("pno scan in progress"));
15297 return -EBUSY;
15298 }
15299
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015300 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015301 //Channel and action frame is pending
15302 //Otherwise Cancel Remain On Channel and allow Scan
15303 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015304 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015305 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015307 return -EBUSY;
15308 }
15309
Jeff Johnson295189b2012-06-20 16:38:30 -070015310 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15311 {
15312 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015313 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015314 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015315 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015316 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15317 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015318 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015319 "%s: MAX TM Level Scan not allowed", __func__);
15320 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015321 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015322 }
15323 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15324
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015325 /* Check if scan is allowed at this point of time.
15326 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015327 if (TRUE == pHddCtx->btCoexModeSet)
15328 {
15329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15330 FL("BTCoex Mode operation in progress"));
15331 return -EBUSY;
15332 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015333 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015334 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015335
15336 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15337 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15338 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015339 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15340 pHddCtx->last_scan_reject_reason != curr_reason ||
15341 !pHddCtx->last_scan_reject_timestamp)
15342 {
15343 pHddCtx->last_scan_reject_session_id = curr_session_id;
15344 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015345 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015346 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015347 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015348 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015349 else
15350 {
15351 pHddCtx->scan_reject_cnt++;
15352
Abhishek Singhe4b12562017-06-20 16:53:39 +053015353 if ((pHddCtx->scan_reject_cnt >=
15354 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015355 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015356 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015357 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015358 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015359 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015360 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015361 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015362 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015363 if (pHddCtx->cfg_ini->enableFatalEvent)
15364 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15365 WLAN_LOG_INDICATOR_HOST_DRIVER,
15366 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15367 FALSE, FALSE);
15368 else
15369 {
15370 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015371 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015372 }
15373 }
15374 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015375 return -EBUSY;
15376 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015377 pHddCtx->last_scan_reject_timestamp = 0;
15378 pHddCtx->last_scan_reject_session_id = 0xFF;
15379 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015380 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015381
Jeff Johnson295189b2012-06-20 16:38:30 -070015382 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15383
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015384 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15385 * Becasue of this, driver is assuming that this is not wildcard scan and so
15386 * is not aging out the scan results.
15387 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015388 if ((request->ssids) && (request->n_ssids == 1) &&
15389 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015390 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015391 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015392
15393 if ((request->ssids) && (0 < request->n_ssids))
15394 {
15395 tCsrSSIDInfo *SsidInfo;
15396 int j;
15397 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15398 /* Allocate num_ssid tCsrSSIDInfo structure */
15399 SsidInfo = scanRequest.SSIDs.SSIDList =
15400 ( tCsrSSIDInfo *)vos_mem_malloc(
15401 request->n_ssids*sizeof(tCsrSSIDInfo));
15402
15403 if(NULL == scanRequest.SSIDs.SSIDList)
15404 {
15405 hddLog(VOS_TRACE_LEVEL_ERROR,
15406 "%s: memory alloc failed SSIDInfo buffer", __func__);
15407 return -ENOMEM;
15408 }
15409
15410 /* copy all the ssid's and their length */
15411 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15412 {
15413 /* get the ssid length */
15414 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15415 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15416 SsidInfo->SSID.length);
15417 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15418 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15419 j, SsidInfo->SSID.ssId);
15420 }
15421 /* set the scan type to active */
15422 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15423 }
15424 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015425 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015426 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15427 TRACE_CODE_HDD_CFG80211_SCAN,
15428 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 /* set the scan type to active */
15430 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015431 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015432 else
15433 {
15434 /*Set the scan type to default type, in this case it is ACTIVE*/
15435 scanRequest.scanType = pScanInfo->scan_mode;
15436 }
15437 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15438 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015439
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015440 csr_scan_request_assign_bssid(&scanRequest, request);
15441
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 /* set BSSType to default type */
15443 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15444
15445 /*TODO: scan the requested channels only*/
15446
15447 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015448 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015450 hddLog(VOS_TRACE_LEVEL_WARN,
15451 "No of Scan Channels exceeded limit: %d", request->n_channels);
15452 request->n_channels = MAX_CHANNEL;
15453 }
15454
15455 hddLog(VOS_TRACE_LEVEL_INFO,
15456 "No of Scan Channels: %d", request->n_channels);
15457
15458
15459 if( request->n_channels )
15460 {
15461 char chList [(request->n_channels*5)+1];
15462 int len;
15463 channelList = vos_mem_malloc( request->n_channels );
15464 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015465 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015466 hddLog(VOS_TRACE_LEVEL_ERROR,
15467 "%s: memory alloc failed channelList", __func__);
15468 status = -ENOMEM;
15469 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015470 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015471
15472 for( i = 0, len = 0; i < request->n_channels ; i++ )
15473 {
15474 channelList[i] = request->channels[i]->hw_value;
15475 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15476 }
15477
Nirav Shah20ac06f2013-12-12 18:14:06 +053015478 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015479 "Channel-List: %s ", chList);
15480 }
c_hpothu53512302014-04-15 18:49:53 +053015481
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015482 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15483 scanRequest.ChannelInfo.ChannelList = channelList;
15484
15485 /* set requestType to full scan */
15486 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15487
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015488 /* if there is back to back scan happening in driver with in
15489 * nDeferScanTimeInterval interval driver should defer new scan request
15490 * and should provide last cached scan results instead of new channel list.
15491 * This rule is not applicable if scan is p2p scan.
15492 * This condition will work only in case when last request no of channels
15493 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015494 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015495 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015496 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015497
Sushant Kaushik86592172015-04-27 16:35:03 +053015498 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15499 /* if wps ie is NULL , then only defer scan */
15500 if ( pWpsIe == NULL &&
15501 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015502 {
15503 if ( pScanInfo->last_scan_timestamp !=0 &&
15504 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15505 {
15506 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15507 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15508 vos_mem_compare(pScanInfo->last_scan_channelList,
15509 channelList, pScanInfo->last_scan_numChannels))
15510 {
15511 hddLog(VOS_TRACE_LEVEL_WARN,
15512 " New and old station scan time differ is less then %u",
15513 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15514
15515 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015516 pAdapter);
15517
Agarwal Ashish57e84372014-12-05 18:26:53 +053015518 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015519 "Return old cached scan as all channels and no of channels are same");
15520
Agarwal Ashish57e84372014-12-05 18:26:53 +053015521 if (0 > ret)
15522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015523
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015524 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015525
15526 status = eHAL_STATUS_SUCCESS;
15527 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015528 }
15529 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015530 }
15531
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015532 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15533 * search (Flush on both full scan and social scan but not on single
15534 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15535 */
15536
15537 /* Supplicant does single channel scan after 8-way handshake
15538 * and in that case driver shoudnt flush scan results. If
15539 * driver flushes the scan results here and unfortunately if
15540 * the AP doesnt respond to our probe req then association
15541 * fails which is not desired
15542 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015543 if ((request->n_ssids == 1)
15544 && (request->ssids != NULL)
15545 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15546 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015547
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015548 if( is_p2p_scan ||
15549 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015550 {
15551 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15552 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15553 pAdapter->sessionId );
15554 }
15555
15556 if( request->ie_len )
15557 {
15558 /* save this for future association (join requires this) */
15559 /*TODO: Array needs to be converted to dynamic allocation,
15560 * as multiple ie.s can be sent in cfg80211_scan_request structure
15561 * CR 597966
15562 */
15563 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15564 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15565 pScanInfo->scanAddIE.length = request->ie_len;
15566
15567 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15568 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15569 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015571 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015572 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015573 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15574 memcpy( pwextBuf->roamProfile.addIEScan,
15575 request->ie, request->ie_len);
15576 }
15577 else
15578 {
15579 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15580 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015581 }
15582
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015583 }
15584 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15585 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15586
15587 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15588 request->ie_len);
15589 if (pP2pIe != NULL)
15590 {
15591#ifdef WLAN_FEATURE_P2P_DEBUG
15592 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15593 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15594 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015595 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015596 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15597 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15598 "Go nego completed to Connection is started");
15599 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15600 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015601 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015602 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15603 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015604 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015605 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15606 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15607 "Disconnected state to Connection is started");
15608 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15609 "for 4way Handshake");
15610 }
15611#endif
15612
15613 /* no_cck will be set during p2p find to disable 11b rates */
15614 if(TRUE == request->no_cck)
15615 {
15616 hddLog(VOS_TRACE_LEVEL_INFO,
15617 "%s: This is a P2P Search", __func__);
15618 scanRequest.p2pSearch = 1;
15619
15620 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015621 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015622 /* set requestType to P2P Discovery */
15623 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15624 }
15625
15626 /*
15627 Skip Dfs Channel in case of P2P Search
15628 if it is set in ini file
15629 */
15630 if(cfg_param->skipDfsChnlInP2pSearch)
15631 {
15632 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015633 }
15634 else
15635 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015636 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015637 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015638
Agarwal Ashish4f616132013-12-30 23:32:50 +053015639 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015640 }
15641 }
15642
15643 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15644
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015645#ifdef FEATURE_WLAN_TDLS
15646 /* if tdls disagree scan right now, return immediately.
15647 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15648 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15649 */
15650 status = wlan_hdd_tdls_scan_callback (pAdapter,
15651 wiphy,
15652#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15653 dev,
15654#endif
15655 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015656 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015657 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015658 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015659 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15660 "scan rejected %d", __func__, status);
15661 else
15662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15663 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015664 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015665 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015666 }
15667#endif
15668
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015669 /* acquire the wakelock to avoid the apps suspend during the scan. To
15670 * address the following issues.
15671 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15672 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15673 * for long time, this result in apps running at full power for long time.
15674 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15675 * be stuck in full power because of resume BMPS
15676 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015677 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015678
Nirav Shah20ac06f2013-12-12 18:14:06 +053015679 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15680 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015681 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15682 scanRequest.requestType, scanRequest.scanType,
15683 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015684 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15685
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015686 if (pHddCtx->spoofMacAddr.isEnabled &&
15687 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015688 {
15689 hddLog(VOS_TRACE_LEVEL_INFO,
15690 "%s: MAC Spoofing enabled for current scan", __func__);
15691 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15692 * to fill TxBds for probe request during current scan
15693 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015694 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015695 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015696
15697 if(status != VOS_STATUS_SUCCESS)
15698 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015699 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015700 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015701#ifdef FEATURE_WLAN_TDLS
15702 wlan_hdd_tdls_scan_done_callback(pAdapter);
15703#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015704 goto free_mem;
15705 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015706 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015707 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015708 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015709 pAdapter->sessionId, &scanRequest, &scanId,
15710 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015711
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 if (eHAL_STATUS_SUCCESS != status)
15713 {
15714 hddLog(VOS_TRACE_LEVEL_ERROR,
15715 "%s: sme_ScanRequest returned error %d", __func__, status);
15716 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015717 if(eHAL_STATUS_RESOURCES == status)
15718 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15720 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015721 status = -EBUSY;
15722 } else {
15723 status = -EIO;
15724 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015725 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015726
15727#ifdef FEATURE_WLAN_TDLS
15728 wlan_hdd_tdls_scan_done_callback(pAdapter);
15729#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015730 goto free_mem;
15731 }
15732
15733 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015734 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015735 pAdapter->request = request;
15736 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015737 pScanInfo->no_cck = request->no_cck;
15738 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15739 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15740 pHddCtx->scan_info.last_scan_channelList[i] =
15741 request->channels[i]->hw_value;
15742 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015743
15744 complete(&pScanInfo->scan_req_completion_event);
15745
15746free_mem:
15747 if( scanRequest.SSIDs.SSIDList )
15748 {
15749 vos_mem_free(scanRequest.SSIDs.SSIDList);
15750 }
15751
15752 if( channelList )
15753 vos_mem_free( channelList );
15754
15755 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015756 return status;
15757}
15758
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015759int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15760#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15761 struct net_device *dev,
15762#endif
15763 struct cfg80211_scan_request *request)
15764{
15765 int ret;
15766
15767 vos_ssr_protect(__func__);
15768 ret = __wlan_hdd_cfg80211_scan(wiphy,
15769#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15770 dev,
15771#endif
15772 request);
15773 vos_ssr_unprotect(__func__);
15774
15775 return ret;
15776}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015777
15778void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15779{
15780 v_U8_t iniDot11Mode =
15781 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15782 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15783
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015784 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15785 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015786 switch ( iniDot11Mode )
15787 {
15788 case eHDD_DOT11_MODE_AUTO:
15789 case eHDD_DOT11_MODE_11ac:
15790 case eHDD_DOT11_MODE_11ac_ONLY:
15791#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015792 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15793 sme_IsFeatureSupportedByFW(DOT11AC) )
15794 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15795 else
15796 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015797#else
15798 hddDot11Mode = eHDD_DOT11_MODE_11n;
15799#endif
15800 break;
15801 case eHDD_DOT11_MODE_11n:
15802 case eHDD_DOT11_MODE_11n_ONLY:
15803 hddDot11Mode = eHDD_DOT11_MODE_11n;
15804 break;
15805 default:
15806 hddDot11Mode = iniDot11Mode;
15807 break;
15808 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015809#ifdef WLAN_FEATURE_AP_HT40_24G
15810 if (operationChannel > SIR_11B_CHANNEL_END)
15811#endif
15812 {
15813 /* This call decides required channel bonding mode */
15814 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015815 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015816 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015817 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015818}
15819
Jeff Johnson295189b2012-06-20 16:38:30 -070015820/*
15821 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015822 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015823 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015824int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015825 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15826 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015827{
15828 int status = 0;
15829 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015830 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015831 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015832 v_U32_t roamId;
15833 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015834 eCsrAuthType RSNAuthType;
15835
15836 ENTER();
15837
15838 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015839 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015840 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015841
15842 status = wlan_hdd_validate_context(pHddCtx);
15843 if (status)
15844 {
Yue Mae36e3552014-03-05 17:06:20 -080015845 return status;
15846 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015847
Jeff Johnson295189b2012-06-20 16:38:30 -070015848 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15849 {
15850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15851 return -EINVAL;
15852 }
15853
Nitesh Shah9b066282017-06-06 18:05:52 +053015854
Jeff Johnson295189b2012-06-20 16:38:30 -070015855 pRoamProfile = &pWextState->roamProfile;
15856
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015857 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015858 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015859 hdd_station_ctx_t *pHddStaCtx;
15860 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015861 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015862
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015863 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15864
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015865 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15867 {
15868 /*QoS not enabled in cfg file*/
15869 pRoamProfile->uapsd_mask = 0;
15870 }
15871 else
15872 {
15873 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015874 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015875 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15876 }
15877
15878 pRoamProfile->SSIDs.numOfSSIDs = 1;
15879 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15880 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015881 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015882 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15883 ssid, ssid_len);
15884
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015885 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15886 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15887
Jeff Johnson295189b2012-06-20 16:38:30 -070015888 if (bssid)
15889 {
15890 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015891 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015893 /* Save BSSID in seperate variable as well, as RoamProfile
15894 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 case of join failure we should send valid BSSID to supplicant
15896 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015897 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015899
Jeff Johnson295189b2012-06-20 16:38:30 -070015900 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015901 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015902 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015903 /* Store bssid_hint to use in the scan filter. */
15904 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15905 WNI_CFG_BSSID_LEN);
15906 /*
15907 * Save BSSID in seperate variable as well, as RoamProfile
15908 * BSSID is getting zeroed out in the association process. And in
15909 * case of join failure we should send valid BSSID to supplicant
15910 */
15911 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15912 WNI_CFG_BSSID_LEN);
15913 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15914 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015915 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015916
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015917
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015918 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15919 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015920 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15921 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015922 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015923 /*set gen ie*/
15924 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15925 /*set auth*/
15926 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15927 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015928#ifdef FEATURE_WLAN_WAPI
15929 if (pAdapter->wapi_info.nWapiMode)
15930 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015931 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015932 switch (pAdapter->wapi_info.wapiAuthMode)
15933 {
15934 case WAPI_AUTH_MODE_PSK:
15935 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015936 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015937 pAdapter->wapi_info.wapiAuthMode);
15938 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15939 break;
15940 }
15941 case WAPI_AUTH_MODE_CERT:
15942 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015943 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 pAdapter->wapi_info.wapiAuthMode);
15945 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15946 break;
15947 }
15948 } // End of switch
15949 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15950 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15951 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015952 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015953 pRoamProfile->AuthType.numEntries = 1;
15954 pRoamProfile->EncryptionType.numEntries = 1;
15955 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15956 pRoamProfile->mcEncryptionType.numEntries = 1;
15957 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15958 }
15959 }
15960#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015961#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015962 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015963 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15964 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15965 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015966 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15967 sizeof (tSirGtkOffloadParams));
15968 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015969 }
15970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015971 pRoamProfile->csrPersona = pAdapter->device_mode;
15972
Jeff Johnson32d95a32012-09-10 13:15:23 -070015973 if( operatingChannel )
15974 {
15975 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15976 pRoamProfile->ChannelInfo.numOfChannels = 1;
15977 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015978 else
15979 {
15980 pRoamProfile->ChannelInfo.ChannelList = NULL;
15981 pRoamProfile->ChannelInfo.numOfChannels = 0;
15982 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015983 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15984 {
15985 hdd_select_cbmode(pAdapter,operatingChannel);
15986 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015987
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015988 /*
15989 * Change conn_state to connecting before sme_RoamConnect(),
15990 * because sme_RoamConnect() has a direct path to call
15991 * hdd_smeRoamCallback(), which will change the conn_state
15992 * If direct path, conn_state will be accordingly changed
15993 * to NotConnected or Associated by either
15994 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15995 * in sme_RoamCallback()
15996 * if sme_RomConnect is to be queued,
15997 * Connecting state will remain until it is completed.
15998 * If connection state is not changed,
15999 * connection state will remain in eConnectionState_NotConnected state.
16000 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16001 * if conn state is eConnectionState_NotConnected.
16002 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16003 * informed of connect result indication which is an issue.
16004 */
16005
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016006 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16007 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016008 {
16009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016010 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016011 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16012 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016013 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16014 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016015 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016016
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016017 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 pAdapter->sessionId, pRoamProfile, &roamId);
16019
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016020 if ((eHAL_STATUS_SUCCESS != status) &&
16021 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16022 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016023
16024 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016025 hddLog(VOS_TRACE_LEVEL_ERROR,
16026 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16027 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016028 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016029 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016030 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016031 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016032
16033 pRoamProfile->ChannelInfo.ChannelList = NULL;
16034 pRoamProfile->ChannelInfo.numOfChannels = 0;
16035
Jeff Johnson295189b2012-06-20 16:38:30 -070016036 }
16037 else
16038 {
16039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16040 return -EINVAL;
16041 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016042 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 return status;
16044}
16045
16046/*
16047 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16048 * This function is used to set the authentication type (OPEN/SHARED).
16049 *
16050 */
16051static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16052 enum nl80211_auth_type auth_type)
16053{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016054 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016055 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16056
16057 ENTER();
16058
16059 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016060 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016061 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016063 hddLog(VOS_TRACE_LEVEL_INFO,
16064 "%s: set authentication type to AUTOSWITCH", __func__);
16065 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16066 break;
16067
16068 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016069#ifdef WLAN_FEATURE_VOWIFI_11R
16070 case NL80211_AUTHTYPE_FT:
16071#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016072 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016073 "%s: set authentication type to OPEN", __func__);
16074 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16075 break;
16076
16077 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016078 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016079 "%s: set authentication type to SHARED", __func__);
16080 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16081 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016082#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016083 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016084 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016085 "%s: set authentication type to CCKM WPA", __func__);
16086 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16087 break;
16088#endif
16089
16090
16091 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016092 hddLog(VOS_TRACE_LEVEL_ERROR,
16093 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016094 auth_type);
16095 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16096 return -EINVAL;
16097 }
16098
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016099 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 pHddStaCtx->conn_info.authType;
16101 return 0;
16102}
16103
16104/*
16105 * FUNCTION: wlan_hdd_set_akm_suite
16106 * This function is used to set the key mgmt type(PSK/8021x).
16107 *
16108 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016109static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 u32 key_mgmt
16111 )
16112{
16113 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16114 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016115 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016116#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016117#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016118#endif
16119#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016120#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016121#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016122 /*set key mgmt type*/
16123 switch(key_mgmt)
16124 {
16125 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016126 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016127#ifdef WLAN_FEATURE_VOWIFI_11R
16128 case WLAN_AKM_SUITE_FT_PSK:
16129#endif
16130 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016131 __func__);
16132 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16133 break;
16134
16135 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016136 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016137#ifdef WLAN_FEATURE_VOWIFI_11R
16138 case WLAN_AKM_SUITE_FT_8021X:
16139#endif
16140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 __func__);
16142 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16143 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016144#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016145#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16146#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16147 case WLAN_AKM_SUITE_CCKM:
16148 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16149 __func__);
16150 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16151 break;
16152#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016153#ifndef WLAN_AKM_SUITE_OSEN
16154#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16155 case WLAN_AKM_SUITE_OSEN:
16156 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16157 __func__);
16158 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16159 break;
16160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016161
16162 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016164 __func__, key_mgmt);
16165 return -EINVAL;
16166
16167 }
16168 return 0;
16169}
16170
16171/*
16172 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016173 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 * (NONE/WEP40/WEP104/TKIP/CCMP).
16175 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016176static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16177 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 bool ucast
16179 )
16180{
16181 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016182 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016183 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16184
16185 ENTER();
16186
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016187 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016190 __func__, cipher);
16191 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16192 }
16193 else
16194 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016195
Jeff Johnson295189b2012-06-20 16:38:30 -070016196 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016197 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016198 {
16199 case IW_AUTH_CIPHER_NONE:
16200 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16201 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016202
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016204 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016206
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016208 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016209 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016210
Jeff Johnson295189b2012-06-20 16:38:30 -070016211 case WLAN_CIPHER_SUITE_TKIP:
16212 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16213 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016214
Jeff Johnson295189b2012-06-20 16:38:30 -070016215 case WLAN_CIPHER_SUITE_CCMP:
16216 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16217 break;
16218#ifdef FEATURE_WLAN_WAPI
16219 case WLAN_CIPHER_SUITE_SMS4:
16220 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16221 break;
16222#endif
16223
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016224#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016225 case WLAN_CIPHER_SUITE_KRK:
16226 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16227 break;
16228#endif
16229 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016231 __func__, cipher);
16232 return -EOPNOTSUPP;
16233 }
16234 }
16235
16236 if (ucast)
16237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016239 __func__, encryptionType);
16240 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16241 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016242 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016243 encryptionType;
16244 }
16245 else
16246 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016247 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016248 __func__, encryptionType);
16249 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16250 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16251 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16252 }
16253
16254 return 0;
16255}
16256
16257
16258/*
16259 * FUNCTION: wlan_hdd_cfg80211_set_ie
16260 * This function is used to parse WPA/RSN IE's.
16261 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016262int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016263#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16264 const u8 *ie,
16265#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016266 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016267#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016268 size_t ie_len
16269 )
16270{
16271 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16273 const u8 *genie = ie;
16274#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016276#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016277 v_U16_t remLen = ie_len;
16278#ifdef FEATURE_WLAN_WAPI
16279 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16280 u16 *tmp;
16281 v_U16_t akmsuiteCount;
16282 int *akmlist;
16283#endif
16284 ENTER();
16285
16286 /* clear previous assocAddIE */
16287 pWextState->assocAddIE.length = 0;
16288 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016289 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016290
16291 while (remLen >= 2)
16292 {
16293 v_U16_t eLen = 0;
16294 v_U8_t elementId;
16295 elementId = *genie++;
16296 eLen = *genie++;
16297 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016298
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016299 /* Sanity check on eLen */
16300 if (eLen > remLen) {
16301 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16302 __func__, eLen, elementId);
16303 VOS_ASSERT(0);
16304 return -EINVAL;
16305 }
16306
Arif Hussain6d2a3322013-11-17 19:50:10 -080016307 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016308 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016309
16310 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016311 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016312 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016313 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 -070016314 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016315 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016316 "%s: Invalid WPA IE", __func__);
16317 return -EINVAL;
16318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016319 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016320 {
16321 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016322 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016323 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016324
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016325 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016326 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016327 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16328 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016329 VOS_ASSERT(0);
16330 return -ENOMEM;
16331 }
16332 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16333 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16334 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016335
Jeff Johnson295189b2012-06-20 16:38:30 -070016336 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16337 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16338 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16339 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016340 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16341 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016342 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16343 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16344 __func__, eLen);
16345 VOS_ASSERT(0);
16346 return -EINVAL;
16347 }
16348
Jeff Johnson295189b2012-06-20 16:38:30 -070016349 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16350 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16351 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16352 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16353 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16354 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016355 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016356 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016357 {
16358 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016359 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016360 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016361
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016362 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016363 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016364 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16365 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016366 VOS_ASSERT(0);
16367 return -ENOMEM;
16368 }
16369 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16370 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16371 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016372
Jeff Johnson295189b2012-06-20 16:38:30 -070016373 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16374 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16375 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016376#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016377 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16378 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016379 /*Consider WFD IE, only for P2P Client */
16380 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16381 {
16382 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016383 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016385
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016386 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016387 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016388 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16389 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016390 VOS_ASSERT(0);
16391 return -ENOMEM;
16392 }
16393 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16394 // WPS IE + P2P IE + WFD IE
16395 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16396 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016397
Jeff Johnson295189b2012-06-20 16:38:30 -070016398 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16399 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16400 }
16401#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016402 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016403 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016404 HS20_OUI_TYPE_SIZE)) )
16405 {
16406 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016407 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016408 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016409
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016410 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016411 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016412 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16413 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016414 VOS_ASSERT(0);
16415 return -ENOMEM;
16416 }
16417 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16418 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016419
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016420 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16421 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16422 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016423 /* Appending OSEN Information Element in Assiciation Request */
16424 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16425 OSEN_OUI_TYPE_SIZE)) )
16426 {
16427 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16428 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16429 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016430
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016431 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016432 {
16433 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16434 "Need bigger buffer space");
16435 VOS_ASSERT(0);
16436 return -ENOMEM;
16437 }
16438 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16439 pWextState->assocAddIE.length += eLen + 2;
16440
16441 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16442 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16443 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16444 }
16445
Abhishek Singh4322e622015-06-10 15:42:54 +053016446 /* Update only for WPA IE */
16447 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16448 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016449
16450 /* populating as ADDIE in beacon frames */
16451 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016452 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016453 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16454 {
16455 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16456 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16457 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16458 {
16459 hddLog(LOGE,
16460 "Coldn't pass "
16461 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16462 }
16463 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16464 else
16465 hddLog(LOGE,
16466 "Could not pass on "
16467 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16468
16469 /* IBSS mode doesn't contain params->proberesp_ies still
16470 beaconIE's need to be populated in probe response frames */
16471 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16472 {
16473 u16 rem_probe_resp_ie_len = eLen + 2;
16474 u8 probe_rsp_ie_len[3] = {0};
16475 u8 counter = 0;
16476
16477 /* Check Probe Resp Length if it is greater then 255 then
16478 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16479 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16480 not able Store More then 255 bytes into One Variable */
16481
16482 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16483 {
16484 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16485 {
16486 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16487 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16488 }
16489 else
16490 {
16491 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16492 rem_probe_resp_ie_len = 0;
16493 }
16494 }
16495
16496 rem_probe_resp_ie_len = 0;
16497
16498 if (probe_rsp_ie_len[0] > 0)
16499 {
16500 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16501 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16502 (tANI_U8*)(genie - 2),
16503 probe_rsp_ie_len[0], NULL,
16504 eANI_BOOLEAN_FALSE)
16505 == eHAL_STATUS_FAILURE)
16506 {
16507 hddLog(LOGE,
16508 "Could not pass"
16509 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16510 }
16511 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16512 }
16513
16514 if (probe_rsp_ie_len[1] > 0)
16515 {
16516 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16517 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16518 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16519 probe_rsp_ie_len[1], NULL,
16520 eANI_BOOLEAN_FALSE)
16521 == eHAL_STATUS_FAILURE)
16522 {
16523 hddLog(LOGE,
16524 "Could not pass"
16525 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16526 }
16527 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16528 }
16529
16530 if (probe_rsp_ie_len[2] > 0)
16531 {
16532 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16533 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16534 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16535 probe_rsp_ie_len[2], NULL,
16536 eANI_BOOLEAN_FALSE)
16537 == eHAL_STATUS_FAILURE)
16538 {
16539 hddLog(LOGE,
16540 "Could not pass"
16541 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16542 }
16543 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16544 }
16545
16546 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16547 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16548 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16549 {
16550 hddLog(LOGE,
16551 "Could not pass"
16552 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16553 }
16554 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016555 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016556 break;
16557 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016558 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16559 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16560 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16561 VOS_ASSERT(0);
16562 return -EINVAL;
16563 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016564 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16565 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16566 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16567 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16568 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16569 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016570
Abhishek Singhb16f3562016-01-20 11:08:32 +053016571 /* Appending extended capabilities with Interworking or
16572 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016573 *
16574 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016575 * interworkingService or bsstransition bit is set to 1.
16576 * Driver is only interested in interworkingService and
16577 * bsstransition capability from supplicant.
16578 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016579 * required from supplicat, it needs to be handled while
16580 * sending Assoc Req in LIM.
16581 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016582 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016583 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016584 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016586 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016588 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016589 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016590 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16591 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016592 VOS_ASSERT(0);
16593 return -ENOMEM;
16594 }
16595 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16596 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016597
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016598 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16599 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16600 break;
16601 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016602#ifdef FEATURE_WLAN_WAPI
16603 case WLAN_EID_WAPI:
16604 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016605 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016606 pAdapter->wapi_info.nWapiMode);
16607 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016608 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016609 akmsuiteCount = WPA_GET_LE16(tmp);
16610 tmp = tmp + 1;
16611 akmlist = (int *)(tmp);
16612 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16613 {
16614 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16615 }
16616 else
16617 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016618 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016619 VOS_ASSERT(0);
16620 return -EINVAL;
16621 }
16622
16623 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16624 {
16625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016626 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016627 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016628 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016629 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016630 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016632 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16634 }
16635 break;
16636#endif
16637 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016638 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016639 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016640 /* when Unknown IE is received we should break and continue
16641 * to the next IE in the buffer instead we were returning
16642 * so changing this to break */
16643 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016644 }
16645 genie += eLen;
16646 remLen -= eLen;
16647 }
16648 EXIT();
16649 return 0;
16650}
16651
16652/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016653 * FUNCTION: hdd_isWPAIEPresent
16654 * Parse the received IE to find the WPA IE
16655 *
16656 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016657static bool hdd_isWPAIEPresent(
16658#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16659 const u8 *ie,
16660#else
16661 u8 *ie,
16662#endif
16663 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016664{
16665 v_U8_t eLen = 0;
16666 v_U16_t remLen = ie_len;
16667 v_U8_t elementId = 0;
16668
16669 while (remLen >= 2)
16670 {
16671 elementId = *ie++;
16672 eLen = *ie++;
16673 remLen -= 2;
16674 if (eLen > remLen)
16675 {
16676 hddLog(VOS_TRACE_LEVEL_ERROR,
16677 "%s: IE length is wrong %d", __func__, eLen);
16678 return FALSE;
16679 }
16680 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16681 {
16682 /* OUI - 0x00 0X50 0XF2
16683 WPA Information Element - 0x01
16684 WPA version - 0x01*/
16685 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16686 return TRUE;
16687 }
16688 ie += eLen;
16689 remLen -= eLen;
16690 }
16691 return FALSE;
16692}
16693
16694/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016695 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016696 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016697 * parameters during connect operation.
16698 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016699int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016700 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016701 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016702{
16703 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016704 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016705 ENTER();
16706
16707 /*set wpa version*/
16708 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16709
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016710 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016712 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016713 {
16714 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16715 }
16716 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16717 {
16718 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16719 }
16720 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016721
16722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016723 pWextState->wpaVersion);
16724
16725 /*set authentication type*/
16726 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16727
16728 if (0 > status)
16729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016730 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016731 "%s: failed to set authentication type ", __func__);
16732 return status;
16733 }
16734
16735 /*set key mgmt type*/
16736 if (req->crypto.n_akm_suites)
16737 {
16738 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16739 if (0 > status)
16740 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016742 __func__);
16743 return status;
16744 }
16745 }
16746
16747 /*set pairwise cipher type*/
16748 if (req->crypto.n_ciphers_pairwise)
16749 {
16750 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16751 req->crypto.ciphers_pairwise[0], true);
16752 if (0 > status)
16753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016754 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016755 "%s: failed to set unicast cipher type", __func__);
16756 return status;
16757 }
16758 }
16759 else
16760 {
16761 /*Reset previous cipher suite to none*/
16762 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16763 if (0 > status)
16764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016765 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016766 "%s: failed to set unicast cipher type", __func__);
16767 return status;
16768 }
16769 }
16770
16771 /*set group cipher type*/
16772 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16773 false);
16774
16775 if (0 > status)
16776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016778 __func__);
16779 return status;
16780 }
16781
Chet Lanctot186b5732013-03-18 10:26:30 -070016782#ifdef WLAN_FEATURE_11W
16783 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16784#endif
16785
Jeff Johnson295189b2012-06-20 16:38:30 -070016786 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16787 if (req->ie_len)
16788 {
16789 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16790 if ( 0 > status)
16791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016793 __func__);
16794 return status;
16795 }
16796 }
16797
16798 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016799 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016800 {
16801 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16802 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16803 )
16804 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016805 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016806 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016809 __func__);
16810 return -EOPNOTSUPP;
16811 }
16812 else
16813 {
16814 u8 key_len = req->key_len;
16815 u8 key_idx = req->key_idx;
16816
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016817 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016818 && (CSR_MAX_NUM_KEY > key_idx)
16819 )
16820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016821 hddLog(VOS_TRACE_LEVEL_INFO,
16822 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016823 __func__, key_idx, key_len);
16824 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016825 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016826 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016827 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016828 (u8)key_len;
16829 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16830 }
16831 }
16832 }
16833 }
16834
16835 return status;
16836}
16837
16838/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016839 * FUNCTION: wlan_hdd_try_disconnect
16840 * This function is used to disconnect from previous
16841 * connection
16842 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016843int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016844{
16845 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016846 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016847 hdd_station_ctx_t *pHddStaCtx;
16848 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016849 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016850
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016851 ret = wlan_hdd_validate_context(pHddCtx);
16852 if (0 != ret)
16853 {
16854 return ret;
16855 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016856 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16857
16858 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16859
16860 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16861 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016862 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016863 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16864 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016865 /* Indicate disconnect to SME so that in-progress connection or preauth
16866 * can be aborted
16867 */
16868 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16869 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016870 spin_lock_bh(&pAdapter->lock_for_active_session);
16871 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16872 {
16873 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16874 }
16875 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016876 hdd_connSetConnectionState(pHddStaCtx,
16877 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016878 /* Issue disconnect to CSR */
16879 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016880 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016881 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016882 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16883 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16884 hddLog(LOG1,
16885 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16886 } else if ( 0 != status ) {
16887 hddLog(LOGE,
16888 FL("csrRoamDisconnect failure, returned %d"),
16889 (int)status );
16890 result = -EINVAL;
16891 goto disconnected;
16892 }
16893 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016894 &pAdapter->disconnect_comp_var,
16895 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016896 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16897 hddLog(LOGE,
16898 "%s: Failed to disconnect, timed out", __func__);
16899 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016900 }
16901 }
16902 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16903 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016904 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016905 &pAdapter->disconnect_comp_var,
16906 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016907 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016908 {
16909 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016910 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016911 }
16912 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016913disconnected:
16914 hddLog(LOG1,
16915 FL("Set HDD connState to eConnectionState_NotConnected"));
16916 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16917 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016918}
16919
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016920/**
16921 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16922 * @adapter: Pointer to the HDD adapter
16923 * @req: Pointer to the structure cfg_connect_params receieved from user space
16924 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053016925 * This function will start reassociation if prev_bssid is set and bssid/
16926 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016927 *
16928 * Return: success if reassociation is happening
16929 * Error code if reassociation is not permitted or not happening
16930 */
16931#ifdef CFG80211_CONNECT_PREV_BSSID
16932static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16933 struct cfg80211_connect_params *req)
16934{
16935 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053016936 const uint8_t *bssid = NULL;
16937 uint16_t channel = 0;
16938
16939 if (req->bssid)
16940 bssid = req->bssid;
16941 else if (req->bssid_hint)
16942 bssid = req->bssid_hint;
16943
16944 if (req->channel)
16945 channel = req->channel->hw_value;
16946 else if (req->channel_hint)
16947 channel = req->channel_hint->hw_value;
16948
16949 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016950 hddLog(VOS_TRACE_LEVEL_INFO,
16951 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053016952 channel, MAC_ADDR_ARRAY(bssid));
16953 status = hdd_reassoc(adapter, bssid, channel,
16954 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016955 }
16956 return status;
16957}
16958#else
16959static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16960 struct cfg80211_connect_params *req)
16961{
16962 return -EPERM;
16963}
16964#endif
16965
Abhishek Singhe3beee22017-07-31 15:35:40 +053016966/**
16967 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16968 * connect in HT20 mode
16969 * @hdd_ctx: hdd context
16970 * @adapter: Pointer to the HDD adapter
16971 * @req: Pointer to the structure cfg_connect_params receieved from user space
16972 *
16973 * This function will check if supplicant has indicated to to connect in HT20
16974 * mode. this is currently applicable only for 2.4Ghz mode only.
16975 * if feature is enabled and supplicant indicate HT20 set
16976 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16977 *
16978 * Return: void
16979 */
16980#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16981static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16982 hdd_adapter_t *adapter,
16983 struct cfg80211_connect_params *req)
16984{
16985 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16986 tCsrRoamProfile *roam_profile;
16987
16988 roam_profile = &wext_state->roamProfile;
16989 roam_profile->force_24ghz_in_ht20 = false;
16990 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16991 !(req->ht_capa.cap_info &
16992 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16993 roam_profile->force_24ghz_in_ht20 = true;
16994
16995 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16996 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16997}
16998#else
16999static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17000 hdd_adapter_t *adapter,
17001 struct cfg80211_connect_params *req)
17002{
17003 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17004 tCsrRoamProfile *roam_profile;
17005
17006 roam_profile = &wext_state->roamProfile;
17007 roam_profile->force_24ghz_in_ht20 = false;
17008}
17009#endif
17010
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017011/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017012 * FUNCTION: __wlan_hdd_cfg80211_connect
17013 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017014 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017015static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017016 struct net_device *ndev,
17017 struct cfg80211_connect_params *req
17018 )
17019{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017020 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017021 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017022#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17023 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017024 const u8 *bssid_hint = req->bssid_hint;
17025#else
17026 const u8 *bssid_hint = NULL;
17027#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017030 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017031
17032 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017033
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17035 TRACE_CODE_HDD_CFG80211_CONNECT,
17036 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017037 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017038 "%s: device_mode = %s (%d)", __func__,
17039 hdd_device_modetoString(pAdapter->device_mode),
17040 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017041
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017042 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017043 if (!pHddCtx)
17044 {
17045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17046 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017047 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017048 }
17049
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017050 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017051 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017052 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017053 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017054 }
17055
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017056 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17057 return -EINVAL;
17058
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017059 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17060 if (0 == status)
17061 return status;
17062
Agarwal Ashish51325b52014-06-16 16:50:49 +053017063
Jeff Johnson295189b2012-06-20 16:38:30 -070017064#ifdef WLAN_BTAMP_FEATURE
17065 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017066 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017068 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017069 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017070 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017071 }
17072#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017073
17074 //If Device Mode is Station Concurrent Sessions Exit BMps
17075 //P2P Mode will be taken care in Open/close adapter
17076 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017077 (vos_concurrent_open_sessions_running())) {
17078 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17079 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017080 }
17081
17082 /*Try disconnecting if already in connected state*/
17083 status = wlan_hdd_try_disconnect(pAdapter);
17084 if ( 0 > status)
17085 {
17086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17087 " connection"));
17088 return -EALREADY;
17089 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017090 /* Check for max concurrent connections after doing disconnect if any*/
17091 if (vos_max_concurrent_connections_reached()) {
17092 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17093 return -ECONNREFUSED;
17094 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017095
Jeff Johnson295189b2012-06-20 16:38:30 -070017096 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017097 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017098
17099 if ( 0 > status)
17100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017102 __func__);
17103 return status;
17104 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017105
17106 if (pHddCtx->spoofMacAddr.isEnabled)
17107 {
17108 hddLog(VOS_TRACE_LEVEL_INFO,
17109 "%s: MAC Spoofing enabled ", __func__);
17110 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17111 * to fill TxBds for probe request during SSID scan which may happen
17112 * as part of connect command
17113 */
17114 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17115 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17116 if (status != VOS_STATUS_SUCCESS)
17117 return -ECONNREFUSED;
17118 }
17119
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017120 if (req->channel)
17121 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017122 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017123 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017124
17125 /* Abort if any scan is going on */
17126 status = wlan_hdd_scan_abort(pAdapter);
17127 if (0 != status)
17128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17129
Abhishek Singhe3beee22017-07-31 15:35:40 +053017130 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17131
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017132 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17133 req->ssid_len, req->bssid,
17134 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017135
Sushant Kaushikd7083982015-03-18 14:33:24 +053017136 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017137 {
17138 //ReEnable BMPS if disabled
17139 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17140 (NULL != pHddCtx))
17141 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017142 if (pHddCtx->hdd_wlan_suspended)
17143 {
17144 hdd_set_pwrparams(pHddCtx);
17145 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017146 //ReEnable Bmps and Imps back
17147 hdd_enable_bmps_imps(pHddCtx);
17148 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017149 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017150 return status;
17151 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017152 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017153 EXIT();
17154 return status;
17155}
17156
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017157static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17158 struct net_device *ndev,
17159 struct cfg80211_connect_params *req)
17160{
17161 int ret;
17162 vos_ssr_protect(__func__);
17163 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17164 vos_ssr_unprotect(__func__);
17165
17166 return ret;
17167}
Jeff Johnson295189b2012-06-20 16:38:30 -070017168
17169/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017170 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017171 * This function is used to issue a disconnect request to SME
17172 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017173static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017174 struct net_device *dev,
17175 u16 reason
17176 )
17177{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017179 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017180 tCsrRoamProfile *pRoamProfile;
17181 hdd_station_ctx_t *pHddStaCtx;
17182 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017183#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017184 tANI_U8 staIdx;
17185#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017186
Jeff Johnson295189b2012-06-20 16:38:30 -070017187 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017188
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017189 if (!pAdapter) {
17190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17191 return -EINVAL;
17192 }
17193
17194 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17195 if (!pHddStaCtx) {
17196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17197 return -EINVAL;
17198 }
17199
17200 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17201 status = wlan_hdd_validate_context(pHddCtx);
17202 if (0 != status)
17203 {
17204 return status;
17205 }
17206
17207 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17208
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017209 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17210 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17211 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017212 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17213 __func__, hdd_device_modetoString(pAdapter->device_mode),
17214 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017215
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17217 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017218
Jeff Johnson295189b2012-06-20 16:38:30 -070017219 if (NULL != pRoamProfile)
17220 {
17221 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017222 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17223 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017225 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017226 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017227 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017228 switch(reason)
17229 {
17230 case WLAN_REASON_MIC_FAILURE:
17231 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17232 break;
17233
17234 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17235 case WLAN_REASON_DISASSOC_AP_BUSY:
17236 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17237 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17238 break;
17239
17240 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17241 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017242 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017243 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17244 break;
17245
Jeff Johnson295189b2012-06-20 16:38:30 -070017246 default:
17247 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17248 break;
17249 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017250 pScanInfo = &pHddCtx->scan_info;
17251 if (pScanInfo->mScanPending)
17252 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017253 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017254 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017255 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017256 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017257 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017258 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017259#ifdef FEATURE_WLAN_TDLS
17260 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017261 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017262 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017263 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17264 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017265 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017266 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017267 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017269 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017270 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017271 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017272 status = sme_DeleteTdlsPeerSta(
17273 WLAN_HDD_GET_HAL_CTX(pAdapter),
17274 pAdapter->sessionId,
17275 mac);
17276 if (status != eHAL_STATUS_SUCCESS) {
17277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17278 return -EPERM;
17279 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017280 }
17281 }
17282#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017283
17284 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17285 reasonCode,
17286 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017287 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17288 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017289 {
17290 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017291 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017292 __func__, (int)status );
17293 return -EINVAL;
17294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017295 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017296 else
17297 {
17298 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17299 "called while in %d state", __func__,
17300 pHddStaCtx->conn_info.connState);
17301 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017302 }
17303 else
17304 {
17305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17306 }
17307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017308 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017309 return status;
17310}
17311
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017312static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17313 struct net_device *dev,
17314 u16 reason
17315 )
17316{
17317 int ret;
17318 vos_ssr_protect(__func__);
17319 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17320 vos_ssr_unprotect(__func__);
17321
17322 return ret;
17323}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017324
Jeff Johnson295189b2012-06-20 16:38:30 -070017325/*
17326 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017327 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017328 * settings in IBSS mode.
17329 */
17330static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017331 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017332 struct cfg80211_ibss_params *params
17333 )
17334{
17335 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017336 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017337 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017338 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17339 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017340
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 ENTER();
17342
17343 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017344 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017345
17346 if (params->ie_len && ( NULL != params->ie) )
17347 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017348 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17349 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017350 {
17351 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17352 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17353 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017354 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017355 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017356 tDot11fIEWPA dot11WPAIE;
17357 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017358 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017359
Wilson Yang00256342013-10-10 23:13:38 -070017360 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017361 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17362 params->ie_len, DOT11F_EID_WPA);
17363 if ( NULL != ie )
17364 {
17365 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017366
17367 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17368 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17369 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17370 return -EINVAL;
17371 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017372 // Unpack the WPA IE
17373 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017374 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017375 &ie[2+4],
17376 ie[1] - 4,
17377 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017378 if (DOT11F_FAILED(ret))
17379 {
17380 hddLog(LOGE,
17381 FL("unpack failed status:(0x%08x)"),
17382 ret);
17383 return -EINVAL;
17384 }
17385
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017386 /*Extract the multicast cipher, the encType for unicast
17387 cipher for wpa-none is none*/
17388 encryptionType =
17389 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17390 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017391 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017392
Jeff Johnson295189b2012-06-20 16:38:30 -070017393 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17394
17395 if (0 > status)
17396 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017398 __func__);
17399 return status;
17400 }
17401 }
17402
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017403 pWextState->roamProfile.AuthType.authType[0] =
17404 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017405 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017406 if (params->privacy)
17407 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017408 /* Security enabled IBSS, At this time there is no information available
17409 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017410 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017411 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017412 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017413 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 *enable privacy bit in beacons */
17415
17416 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17417 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017418 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17419 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017420 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17421 pWextState->roamProfile.EncryptionType.numEntries = 1;
17422 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 return status;
17424}
17425
17426/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017427 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017428 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017429 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017430static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017431 struct net_device *dev,
17432 struct cfg80211_ibss_params *params
17433 )
17434{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017436 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17437 tCsrRoamProfile *pRoamProfile;
17438 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17440 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017441 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017442
17443 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017444
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017445 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17446 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17447 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017448 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017449 "%s: device_mode = %s (%d)", __func__,
17450 hdd_device_modetoString(pAdapter->device_mode),
17451 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017452
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017453 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017454 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017455 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017456 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017457 }
17458
17459 if (NULL == pWextState)
17460 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017461 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017462 __func__);
17463 return -EIO;
17464 }
17465
Agarwal Ashish51325b52014-06-16 16:50:49 +053017466 if (vos_max_concurrent_connections_reached()) {
17467 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17468 return -ECONNREFUSED;
17469 }
17470
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017471 /*Try disconnecting if already in connected state*/
17472 status = wlan_hdd_try_disconnect(pAdapter);
17473 if ( 0 > status)
17474 {
17475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17476 " IBSS connection"));
17477 return -EALREADY;
17478 }
17479
Jeff Johnson295189b2012-06-20 16:38:30 -070017480 pRoamProfile = &pWextState->roamProfile;
17481
17482 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17483 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017484 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017485 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017486 return -EINVAL;
17487 }
17488
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017489 /* BSSID is provided by upper layers hence no need to AUTO generate */
17490 if (NULL != params->bssid) {
17491 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17492 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17493 hddLog (VOS_TRACE_LEVEL_ERROR,
17494 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17495 return -EIO;
17496 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017497 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017498 }
krunal sonie9002db2013-11-25 14:24:17 -080017499 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17500 {
17501 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17502 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17503 {
17504 hddLog (VOS_TRACE_LEVEL_ERROR,
17505 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17506 return -EIO;
17507 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017508
17509 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017510 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017511 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017512 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017513
Jeff Johnson295189b2012-06-20 16:38:30 -070017514 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017515 if (NULL !=
17516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17517 params->chandef.chan)
17518#else
17519 params->channel)
17520#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017521 {
17522 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017523 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17524 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17525 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17526 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017527
17528 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017529 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017530 ieee80211_frequency_to_channel(
17531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17532 params->chandef.chan->center_freq);
17533#else
17534 params->channel->center_freq);
17535#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017536
17537 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17538 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017539 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17541 __func__);
17542 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017543 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017544
17545 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017546 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017547 if (channelNum == validChan[indx])
17548 {
17549 break;
17550 }
17551 }
17552 if (indx >= numChans)
17553 {
17554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017555 __func__, channelNum);
17556 return -EINVAL;
17557 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017558 /* Set the Operational Channel */
17559 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17560 channelNum);
17561 pRoamProfile->ChannelInfo.numOfChannels = 1;
17562 pHddStaCtx->conn_info.operationChannel = channelNum;
17563 pRoamProfile->ChannelInfo.ChannelList =
17564 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017565 }
17566
17567 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017568 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017569 if (status < 0)
17570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017572 __func__);
17573 return status;
17574 }
17575
17576 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017577 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017578 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017579 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017580
17581 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017584 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017585 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017586}
17587
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017588static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17589 struct net_device *dev,
17590 struct cfg80211_ibss_params *params
17591 )
17592{
17593 int ret = 0;
17594
17595 vos_ssr_protect(__func__);
17596 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17597 vos_ssr_unprotect(__func__);
17598
17599 return ret;
17600}
17601
Jeff Johnson295189b2012-06-20 16:38:30 -070017602/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017603 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017604 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017606static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017607 struct net_device *dev
17608 )
17609{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017611 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17612 tCsrRoamProfile *pRoamProfile;
17613 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017614 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017615 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017616#ifdef WLAN_FEATURE_RMC
17617 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17618#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017619
17620 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017621
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17623 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17624 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017625 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017626 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017627 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017628 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017629 }
17630
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17632 hdd_device_modetoString(pAdapter->device_mode),
17633 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 if (NULL == pWextState)
17635 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017636 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 __func__);
17638 return -EIO;
17639 }
17640
17641 pRoamProfile = &pWextState->roamProfile;
17642
17643 /* Issue disconnect only if interface type is set to IBSS */
17644 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017646 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017647 __func__);
17648 return -EINVAL;
17649 }
17650
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017651#ifdef WLAN_FEATURE_RMC
17652 /* Clearing add IE of beacon */
17653 if (ccmCfgSetStr(pHddCtx->hHal,
17654 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17655 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17656 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17657 {
17658 hddLog (VOS_TRACE_LEVEL_ERROR,
17659 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17660 return -EINVAL;
17661 }
17662 if (ccmCfgSetInt(pHddCtx->hHal,
17663 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17664 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17665 {
17666 hddLog (VOS_TRACE_LEVEL_ERROR,
17667 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17668 __func__);
17669 return -EINVAL;
17670 }
17671
17672 // Reset WNI_CFG_PROBE_RSP Flags
17673 wlan_hdd_reset_prob_rspies(pAdapter);
17674
17675 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17676 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17677 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17678 {
17679 hddLog (VOS_TRACE_LEVEL_ERROR,
17680 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17681 __func__);
17682 return -EINVAL;
17683 }
17684#endif
17685
Jeff Johnson295189b2012-06-20 16:38:30 -070017686 /* Issue Disconnect request */
17687 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017688 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17689 pAdapter->sessionId,
17690 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17691 if (!HAL_STATUS_SUCCESS(hal_status)) {
17692 hddLog(LOGE,
17693 FL("sme_RoamDisconnect failed hal_status(%d)"),
17694 hal_status);
17695 return -EAGAIN;
17696 }
17697 status = wait_for_completion_timeout(
17698 &pAdapter->disconnect_comp_var,
17699 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17700 if (!status) {
17701 hddLog(LOGE,
17702 FL("wait on disconnect_comp_var failed"));
17703 return -ETIMEDOUT;
17704 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017705
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017706 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017707 return 0;
17708}
17709
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017710static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17711 struct net_device *dev
17712 )
17713{
17714 int ret = 0;
17715
17716 vos_ssr_protect(__func__);
17717 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17718 vos_ssr_unprotect(__func__);
17719
17720 return ret;
17721}
17722
Jeff Johnson295189b2012-06-20 16:38:30 -070017723/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017724 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017725 * This function is used to set the phy parameters
17726 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17727 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017728static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017729 u32 changed)
17730{
17731 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17732 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017733 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017734
17735 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017736
17737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017738 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17739 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017741 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017742 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017743 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017744 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017745 }
17746
Jeff Johnson295189b2012-06-20 16:38:30 -070017747 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17748 {
17749 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17750 WNI_CFG_RTS_THRESHOLD_STAMAX :
17751 wiphy->rts_threshold;
17752
17753 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017754 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017755 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017756 hddLog(VOS_TRACE_LEVEL_ERROR,
17757 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017758 __func__, rts_threshold);
17759 return -EINVAL;
17760 }
17761
17762 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17763 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017764 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017765 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017766 hddLog(VOS_TRACE_LEVEL_ERROR,
17767 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017768 __func__, rts_threshold);
17769 return -EIO;
17770 }
17771
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017772 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017773 rts_threshold);
17774 }
17775
17776 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17777 {
17778 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17779 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17780 wiphy->frag_threshold;
17781
17782 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017783 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017784 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017785 hddLog(VOS_TRACE_LEVEL_ERROR,
17786 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017787 frag_threshold);
17788 return -EINVAL;
17789 }
17790
17791 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17792 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017793 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017794 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017795 hddLog(VOS_TRACE_LEVEL_ERROR,
17796 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017797 __func__, frag_threshold);
17798 return -EIO;
17799 }
17800
17801 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17802 frag_threshold);
17803 }
17804
17805 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17806 || (changed & WIPHY_PARAM_RETRY_LONG))
17807 {
17808 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17809 wiphy->retry_short :
17810 wiphy->retry_long;
17811
17812 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17813 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017816 __func__, retry_value);
17817 return -EINVAL;
17818 }
17819
17820 if (changed & WIPHY_PARAM_RETRY_SHORT)
17821 {
17822 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17823 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017824 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017826 hddLog(VOS_TRACE_LEVEL_ERROR,
17827 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017828 __func__, retry_value);
17829 return -EIO;
17830 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017831 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017832 __func__, retry_value);
17833 }
17834 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17835 {
17836 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17837 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017838 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017840 hddLog(VOS_TRACE_LEVEL_ERROR,
17841 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017842 __func__, retry_value);
17843 return -EIO;
17844 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017845 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017846 __func__, retry_value);
17847 }
17848 }
17849
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017850 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017851 return 0;
17852}
17853
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017854static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17855 u32 changed)
17856{
17857 int ret;
17858
17859 vos_ssr_protect(__func__);
17860 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17861 vos_ssr_unprotect(__func__);
17862
17863 return ret;
17864}
17865
Jeff Johnson295189b2012-06-20 16:38:30 -070017866/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017867 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017868 * This function is used to set the txpower
17869 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017870static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017871#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17872 struct wireless_dev *wdev,
17873#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017874#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017875 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017876#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017877 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017878#endif
17879 int dbm)
17880{
17881 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017882 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017883 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17884 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017885 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017886
17887 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017888
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017889 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17890 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17891 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017892 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017893 if (0 != status)
17894 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017895 return status;
17896 }
17897
17898 hHal = pHddCtx->hHal;
17899
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017900 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17901 dbm, ccmCfgSetCallback,
17902 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017904 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017905 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17906 return -EIO;
17907 }
17908
17909 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17910 dbm);
17911
17912 switch(type)
17913 {
17914 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17915 /* Fall through */
17916 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17917 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17918 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017919 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17920 __func__);
17921 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017922 }
17923 break;
17924 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017926 __func__);
17927 return -EOPNOTSUPP;
17928 break;
17929 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17931 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017932 return -EIO;
17933 }
17934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017935 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017936 return 0;
17937}
17938
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017939static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17940#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17941 struct wireless_dev *wdev,
17942#endif
17943#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17944 enum tx_power_setting type,
17945#else
17946 enum nl80211_tx_power_setting type,
17947#endif
17948 int dbm)
17949{
17950 int ret;
17951 vos_ssr_protect(__func__);
17952 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17953#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17954 wdev,
17955#endif
17956#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17957 type,
17958#else
17959 type,
17960#endif
17961 dbm);
17962 vos_ssr_unprotect(__func__);
17963
17964 return ret;
17965}
17966
Jeff Johnson295189b2012-06-20 16:38:30 -070017967/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017968 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017969 * This function is used to read the txpower
17970 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017971static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017972#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17973 struct wireless_dev *wdev,
17974#endif
17975 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017976{
17977
17978 hdd_adapter_t *pAdapter;
17979 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017980 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017981
Jeff Johnsone7245742012-09-05 17:12:55 -070017982 ENTER();
17983
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017984 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017985 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017986 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017987 *dbm = 0;
17988 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017989 }
17990
Jeff Johnson295189b2012-06-20 16:38:30 -070017991 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17992 if (NULL == pAdapter)
17993 {
17994 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17995 return -ENOENT;
17996 }
17997
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17999 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18000 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018001 wlan_hdd_get_classAstats(pAdapter);
18002 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18003
Jeff Johnsone7245742012-09-05 17:12:55 -070018004 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018005 return 0;
18006}
18007
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018008static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18009#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18010 struct wireless_dev *wdev,
18011#endif
18012 int *dbm)
18013{
18014 int ret;
18015
18016 vos_ssr_protect(__func__);
18017 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18018#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18019 wdev,
18020#endif
18021 dbm);
18022 vos_ssr_unprotect(__func__);
18023
18024 return ret;
18025}
18026
Dustin Brown8c1d4092017-07-28 18:08:01 +053018027/*
18028 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18029 * @stats: summary stats to use as a source
18030 * @info: kernel station_info struct to use as a destination
18031 *
18032 * Return: None
18033 */
18034static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18035 struct station_info *info)
18036{
18037 int i;
18038
18039 info->rx_packets = stats->rx_frm_cnt;
18040 info->tx_packets = 0;
18041 info->tx_retries = 0;
18042 info->tx_failed = 0;
18043
18044 for (i = 0; i < 4; ++i) {
18045 info->tx_packets += stats->tx_frm_cnt[i];
18046 info->tx_retries += stats->multiple_retry_cnt[i];
18047 info->tx_failed += stats->fail_cnt[i];
18048 }
18049
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018050#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18051 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018052 info->filled |= STATION_INFO_TX_PACKETS |
18053 STATION_INFO_TX_RETRIES |
18054 STATION_INFO_TX_FAILED |
18055 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018056#else
18057 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18058 BIT(NL80211_STA_INFO_TX_RETRIES) |
18059 BIT(NL80211_STA_INFO_TX_FAILED) |
18060 BIT(NL80211_STA_INFO_RX_PACKETS);
18061#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018062}
18063
18064/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018065 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18066 * @adapter: sap adapter pointer
18067 * @staid: station id of the client
18068 * @rssi: rssi value to fill
18069 *
18070 * Return: None
18071 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018072void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018073wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18074{
18075 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18076
18077 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18078}
18079
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018080#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18081 !defined(WITH_BACKPORTS)
18082static inline void wlan_hdd_fill_station_info_signal(struct station_info
18083 *sinfo)
18084{
18085 sinfo->filled |= STATION_INFO_SIGNAL;
18086}
18087#else
18088static inline void wlan_hdd_fill_station_info_signal(struct station_info
18089 *sinfo)
18090{
18091 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18092}
18093#endif
18094
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018095/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018096 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18097 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018098 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018099 * @info: kernel station_info struct to populate
18100 *
18101 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18102 * support "station dump" and "station get" for SAP vdevs, even though they
18103 * aren't technically stations.
18104 *
18105 * Return: errno
18106 */
18107static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018108wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18109#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18110 const u8* mac,
18111#else
18112 u8* mac,
18113#endif
18114 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018115{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018116 v_MACADDR_t *peerMacAddr;
18117 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018118 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018119 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018120
18121 status = wlan_hdd_get_station_stats(adapter);
18122 if (!VOS_IS_STATUS_SUCCESS(status)) {
18123 hddLog(VOS_TRACE_LEVEL_ERROR,
18124 "Failed to get SAP stats; status:%d", status);
18125 return 0;
18126 }
18127
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018128 peerMacAddr = (v_MACADDR_t *)mac;
18129 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18130 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18131 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18132
18133 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18134 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018135 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018136 }
18137
Dustin Brown8c1d4092017-07-28 18:08:01 +053018138 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18139
18140 return 0;
18141}
18142
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018143static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18145 const u8* mac,
18146#else
18147 u8* mac,
18148#endif
18149 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018150{
18151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18152 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18153 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018154 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018155
18156 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18157 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018158
18159 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18160 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18161 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18162 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18163 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18164 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18165 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018166 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018167 tANI_U16 myRate;
18168 tANI_U16 currentRate = 0;
18169 tANI_U8 maxSpeedMCS = 0;
18170 tANI_U8 maxMCSIdx = 0;
18171 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018172 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018173 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018174 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018175
Leo Chang6f8870f2013-03-26 18:11:36 -070018176#ifdef WLAN_FEATURE_11AC
18177 tANI_U32 vht_mcs_map;
18178 eDataRate11ACMaxMcs vhtMaxMcs;
18179#endif /* WLAN_FEATURE_11AC */
18180
Jeff Johnsone7245742012-09-05 17:12:55 -070018181 ENTER();
18182
Dustin Brown8c1d4092017-07-28 18:08:01 +053018183 status = wlan_hdd_validate_context(pHddCtx);
18184 if (0 != status)
18185 {
18186 return status;
18187 }
18188
18189 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018190 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018191
Jeff Johnson295189b2012-06-20 16:38:30 -070018192 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18193 (0 == ssidlen))
18194 {
18195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18196 " Invalid ssidlen, %d", __func__, ssidlen);
18197 /*To keep GUI happy*/
18198 return 0;
18199 }
18200
Mukul Sharma811205f2014-07-09 21:07:30 +053018201 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18202 {
18203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18204 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018205 /* return a cached value */
18206 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018207 return 0;
18208 }
18209
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018210 wlan_hdd_get_station_stats(pAdapter);
18211 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018212
Kiet Lam3b17fc82013-09-27 05:24:08 +053018213 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018214 wlan_hdd_get_snr(pAdapter, &snr);
18215 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018216 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018217 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018218 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018219 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018220
c_hpothu09f19542014-05-30 21:53:31 +053018221 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018222 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18223 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018224 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018225 {
18226 rate_flags = pAdapter->maxRateFlags;
18227 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018228
Jeff Johnson295189b2012-06-20 16:38:30 -070018229 //convert to the UI units of 100kbps
18230 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18231
18232#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018233 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 -070018234 sinfo->signal,
18235 pCfg->reportMaxLinkSpeed,
18236 myRate,
18237 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018238 (int) pCfg->linkSpeedRssiMid,
18239 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018240 (int) rate_flags,
18241 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018242#endif //LINKSPEED_DEBUG_ENABLED
18243
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18245 /* assume basic BW. anything else will override this later */
18246 sinfo->txrate.bw = RATE_INFO_BW_20;
18247#endif
18248
Jeff Johnson295189b2012-06-20 16:38:30 -070018249 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18250 {
18251 // we do not want to necessarily report the current speed
18252 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18253 {
18254 // report the max possible speed
18255 rssidx = 0;
18256 }
18257 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18258 {
18259 // report the max possible speed with RSSI scaling
18260 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18261 {
18262 // report the max possible speed
18263 rssidx = 0;
18264 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018265 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018266 {
18267 // report middle speed
18268 rssidx = 1;
18269 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018270 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18271 {
18272 // report middle speed
18273 rssidx = 2;
18274 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018275 else
18276 {
18277 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018278 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018279 }
18280 }
18281 else
18282 {
18283 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18284 hddLog(VOS_TRACE_LEVEL_ERROR,
18285 "%s: Invalid value for reportMaxLinkSpeed: %u",
18286 __func__, pCfg->reportMaxLinkSpeed);
18287 rssidx = 0;
18288 }
18289
18290 maxRate = 0;
18291
18292 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018293 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18294 OperationalRates, &ORLeng))
18295 {
18296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18297 /*To keep GUI happy*/
18298 return 0;
18299 }
18300
Jeff Johnson295189b2012-06-20 16:38:30 -070018301 for (i = 0; i < ORLeng; i++)
18302 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018303 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018304 {
18305 /* Validate Rate Set */
18306 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18307 {
18308 currentRate = supported_data_rate[j].supported_rate[rssidx];
18309 break;
18310 }
18311 }
18312 /* Update MAX rate */
18313 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18314 }
18315
18316 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018317 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18318 ExtendedRates, &ERLeng))
18319 {
18320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18321 /*To keep GUI happy*/
18322 return 0;
18323 }
18324
Jeff Johnson295189b2012-06-20 16:38:30 -070018325 for (i = 0; i < ERLeng; i++)
18326 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018327 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018328 {
18329 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18330 {
18331 currentRate = supported_data_rate[j].supported_rate[rssidx];
18332 break;
18333 }
18334 }
18335 /* Update MAX rate */
18336 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18337 }
c_hpothu79aab322014-07-14 21:11:01 +053018338
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018339 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018340 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018341 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018342 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018343 {
c_hpothu79aab322014-07-14 21:11:01 +053018344 if (rate_flags & eHAL_TX_RATE_VHT80)
18345 mode = 2;
18346 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18347 mode = 1;
18348 else
18349 mode = 0;
18350
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018351 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18352 MCSRates, &MCSLeng))
18353 {
18354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18355 /*To keep GUI happy*/
18356 return 0;
18357 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018358 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018359#ifdef WLAN_FEATURE_11AC
18360 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018361 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018362 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018363 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018364 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018365 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018366 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018367 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018368 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018369 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018370 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018371 maxMCSIdx = 7;
18372 }
18373 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18374 {
18375 maxMCSIdx = 8;
18376 }
18377 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18378 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018379 //VHT20 is supporting 0~8
18380 if (rate_flags & eHAL_TX_RATE_VHT20)
18381 maxMCSIdx = 8;
18382 else
18383 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018384 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018385
c_hpothu79aab322014-07-14 21:11:01 +053018386 if (0 != rssidx)/*check for scaled */
18387 {
18388 //get middle rate MCS index if rssi=1/2
18389 for (i=0; i <= maxMCSIdx; i++)
18390 {
18391 if (sinfo->signal <= rssiMcsTbl[mode][i])
18392 {
18393 maxMCSIdx = i;
18394 break;
18395 }
18396 }
18397 }
18398
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018399 if (rate_flags & eHAL_TX_RATE_VHT80)
18400 {
18401 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18402 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18403 }
18404 else if (rate_flags & eHAL_TX_RATE_VHT40)
18405 {
18406 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18407 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18408 }
18409 else if (rate_flags & eHAL_TX_RATE_VHT20)
18410 {
18411 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18412 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18413 }
18414
Leo Chang6f8870f2013-03-26 18:11:36 -070018415 maxSpeedMCS = 1;
18416 if (currentRate > maxRate)
18417 {
18418 maxRate = currentRate;
18419 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018420
Leo Chang6f8870f2013-03-26 18:11:36 -070018421 }
18422 else
18423#endif /* WLAN_FEATURE_11AC */
18424 {
18425 if (rate_flags & eHAL_TX_RATE_HT40)
18426 {
18427 rateFlag |= 1;
18428 }
18429 if (rate_flags & eHAL_TX_RATE_SGI)
18430 {
18431 rateFlag |= 2;
18432 }
18433
Girish Gowli01abcee2014-07-31 20:18:55 +053018434 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018435 if (rssidx == 1 || rssidx == 2)
18436 {
18437 //get middle rate MCS index if rssi=1/2
18438 for (i=0; i <= 7; i++)
18439 {
18440 if (sinfo->signal <= rssiMcsTbl[mode][i])
18441 {
18442 temp = i+1;
18443 break;
18444 }
18445 }
18446 }
c_hpothu79aab322014-07-14 21:11:01 +053018447
18448 for (i = 0; i < MCSLeng; i++)
18449 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018450 for (j = 0; j < temp; j++)
18451 {
18452 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18453 {
18454 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018455 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018456 break;
18457 }
18458 }
18459 if ((j < temp) && (currentRate > maxRate))
18460 {
18461 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018463 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018464 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018465 }
18466 }
18467
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018468 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18469 {
18470 maxRate = myRate;
18471 maxSpeedMCS = 1;
18472 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18473 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018474 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018475 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018476 {
18477 maxRate = myRate;
18478 if (rate_flags & eHAL_TX_RATE_LEGACY)
18479 {
18480 maxSpeedMCS = 0;
18481 }
18482 else
18483 {
18484 maxSpeedMCS = 1;
18485 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18486 }
18487 }
18488
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018489 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018490 {
18491 sinfo->txrate.legacy = maxRate;
18492#ifdef LINKSPEED_DEBUG_ENABLED
18493 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18494#endif //LINKSPEED_DEBUG_ENABLED
18495 }
18496 else
18497 {
18498 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018499#ifdef WLAN_FEATURE_11AC
18500 sinfo->txrate.nss = 1;
18501 if (rate_flags & eHAL_TX_RATE_VHT80)
18502 {
18503 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18505 defined(WITH_BACKPORTS)
18506 sinfo->txrate.bw = RATE_INFO_BW_80;
18507#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018508 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018509#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018510 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018511 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018512 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018513 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018514#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18515 defined(WITH_BACKPORTS)
18516 sinfo->txrate.bw = RATE_INFO_BW_40;
18517#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018518 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018519#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018520 }
18521 else if (rate_flags & eHAL_TX_RATE_VHT20)
18522 {
18523 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18524 }
18525#endif /* WLAN_FEATURE_11AC */
18526 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18527 {
18528 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18529 if (rate_flags & eHAL_TX_RATE_HT40)
18530 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18532 defined(WITH_BACKPORTS)
18533 sinfo->txrate.bw = RATE_INFO_BW_40;
18534#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018535 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018536#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018537 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018538 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018539 if (rate_flags & eHAL_TX_RATE_SGI)
18540 {
18541 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18542 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018543
Jeff Johnson295189b2012-06-20 16:38:30 -070018544#ifdef LINKSPEED_DEBUG_ENABLED
18545 pr_info("Reporting MCS rate %d flags %x\n",
18546 sinfo->txrate.mcs,
18547 sinfo->txrate.flags );
18548#endif //LINKSPEED_DEBUG_ENABLED
18549 }
18550 }
18551 else
18552 {
18553 // report current rate instead of max rate
18554
18555 if (rate_flags & eHAL_TX_RATE_LEGACY)
18556 {
18557 //provide to the UI in units of 100kbps
18558 sinfo->txrate.legacy = myRate;
18559#ifdef LINKSPEED_DEBUG_ENABLED
18560 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18561#endif //LINKSPEED_DEBUG_ENABLED
18562 }
18563 else
18564 {
18565 //must be MCS
18566 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018567#ifdef WLAN_FEATURE_11AC
18568 sinfo->txrate.nss = 1;
18569 if (rate_flags & eHAL_TX_RATE_VHT80)
18570 {
18571 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18572 }
18573 else
18574#endif /* WLAN_FEATURE_11AC */
18575 {
18576 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18577 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018578 if (rate_flags & eHAL_TX_RATE_SGI)
18579 {
18580 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18581 }
18582 if (rate_flags & eHAL_TX_RATE_HT40)
18583 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18585 defined(WITH_BACKPORTS)
18586 sinfo->txrate.bw = RATE_INFO_BW_40;
18587#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018588 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018589#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018590 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018591#ifdef WLAN_FEATURE_11AC
18592 else if (rate_flags & eHAL_TX_RATE_VHT80)
18593 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018594#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18595 defined(WITH_BACKPORTS)
18596 sinfo->txrate.bw = RATE_INFO_BW_80;
18597#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018598 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018599#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018600 }
18601#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018602#ifdef LINKSPEED_DEBUG_ENABLED
18603 pr_info("Reporting actual MCS rate %d flags %x\n",
18604 sinfo->txrate.mcs,
18605 sinfo->txrate.flags );
18606#endif //LINKSPEED_DEBUG_ENABLED
18607 }
18608 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018609
18610#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18611 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018612 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018613#else
18614 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018616
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018617 sinfo->tx_packets =
18618 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18619 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18620 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18621 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18622
18623 sinfo->tx_retries =
18624 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18625 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18626 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18627 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18628
18629 sinfo->tx_failed =
18630 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18631 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18632 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18633 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18634
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018635#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18636 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018637 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018638 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018639 STATION_INFO_TX_PACKETS |
18640 STATION_INFO_TX_RETRIES |
18641 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018642#else
18643 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18644 BIT(NL80211_STA_INFO_TX_PACKETS) |
18645 BIT(NL80211_STA_INFO_TX_RETRIES) |
18646 BIT(NL80211_STA_INFO_TX_FAILED);
18647#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018648
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018649 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018650
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018651 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18652 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018653 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18654 &sinfo->txrate, sizeof(sinfo->txrate));
18655
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018656 if (rate_flags & eHAL_TX_RATE_LEGACY)
18657 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18658 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18659 sinfo->rx_packets);
18660 else
18661 hddLog(LOG1,
18662 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18663 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18664 sinfo->tx_packets, sinfo->rx_packets);
18665
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018666 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18667 TRACE_CODE_HDD_CFG80211_GET_STA,
18668 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018669 EXIT();
18670 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018671}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18673static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18674 const u8* mac, struct station_info *sinfo)
18675#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018676static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18677 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018678#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018679{
18680 int ret;
18681
18682 vos_ssr_protect(__func__);
18683 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18684 vos_ssr_unprotect(__func__);
18685
18686 return ret;
18687}
18688
18689static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018690 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018691{
18692 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018693 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018694 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018695 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018696
Jeff Johnsone7245742012-09-05 17:12:55 -070018697 ENTER();
18698
Jeff Johnson295189b2012-06-20 16:38:30 -070018699 if (NULL == pAdapter)
18700 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018702 return -ENODEV;
18703 }
18704
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18706 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18707 pAdapter->sessionId, timeout));
18708
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018709 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018710 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018711 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018712 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018713 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018714 }
18715
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018716 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18717 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18718 (pHddCtx->cfg_ini->fhostArpOffload) &&
18719 (eConnectionState_Associated ==
18720 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18721 {
Amar Singhald53568e2013-09-26 11:03:45 -070018722
18723 hddLog(VOS_TRACE_LEVEL_INFO,
18724 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018725 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018726 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18727 {
18728 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018729 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018730 __func__, vos_status);
18731 }
18732 }
18733
Jeff Johnson295189b2012-06-20 16:38:30 -070018734 /**The get power cmd from the supplicant gets updated by the nl only
18735 *on successful execution of the function call
18736 *we are oppositely mapped w.r.t mode in the driver
18737 **/
18738 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18739
18740 if (VOS_STATUS_E_FAILURE == vos_status)
18741 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18743 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018744 return -EINVAL;
18745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018746 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018747 return 0;
18748}
18749
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018750static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18751 struct net_device *dev, bool mode, int timeout)
18752{
18753 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018754
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018755 vos_ssr_protect(__func__);
18756 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18757 vos_ssr_unprotect(__func__);
18758
18759 return ret;
18760}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018761
Jeff Johnson295189b2012-06-20 16:38:30 -070018762#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018763static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18764 struct net_device *netdev,
18765 u8 key_index)
18766{
18767 ENTER();
18768 return 0;
18769}
18770
Jeff Johnson295189b2012-06-20 16:38:30 -070018771static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018772 struct net_device *netdev,
18773 u8 key_index)
18774{
18775 int ret;
18776 vos_ssr_protect(__func__);
18777 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18778 vos_ssr_unprotect(__func__);
18779 return ret;
18780}
18781#endif //LINUX_VERSION_CODE
18782
18783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18784static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18785 struct net_device *dev,
18786 struct ieee80211_txq_params *params)
18787{
18788 ENTER();
18789 return 0;
18790}
18791#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18792static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18793 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018794{
Jeff Johnsone7245742012-09-05 17:12:55 -070018795 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018796 return 0;
18797}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018798#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018799
18800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18801static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018802 struct net_device *dev,
18803 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018804{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018805 int ret;
18806
18807 vos_ssr_protect(__func__);
18808 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18809 vos_ssr_unprotect(__func__);
18810 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018811}
18812#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18813static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18814 struct ieee80211_txq_params *params)
18815{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018816 int ret;
18817
18818 vos_ssr_protect(__func__);
18819 ret = __wlan_hdd_set_txq_params(wiphy, params);
18820 vos_ssr_unprotect(__func__);
18821 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018822}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018823#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018824
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018825static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018826 struct net_device *dev,
18827 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018828{
18829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018830 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018831 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018832 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018833 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018834 v_CONTEXT_t pVosContext = NULL;
18835 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018836
Jeff Johnsone7245742012-09-05 17:12:55 -070018837 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018838
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018839 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018840 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018842 return -EINVAL;
18843 }
18844
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018845 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18846 TRACE_CODE_HDD_CFG80211_DEL_STA,
18847 pAdapter->sessionId, pAdapter->device_mode));
18848
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018849 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18850 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018851 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018852 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018853 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018854 }
18855
Jeff Johnson295189b2012-06-20 16:38:30 -070018856 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018857 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018858 )
18859 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018860 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18861 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18862 if(pSapCtx == NULL){
18863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18864 FL("psapCtx is NULL"));
18865 return -ENOENT;
18866 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018867 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18868 {
18869 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18870 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18871 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18872 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018873 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018874 {
18875 v_U16_t i;
18876 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18877 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018878 if ((pSapCtx->aStaInfo[i].isUsed) &&
18879 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018880 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018881 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018882 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018883 ETHER_ADDR_LEN);
18884
Jeff Johnson295189b2012-06-20 16:38:30 -070018885 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018886 "%s: Delete STA with MAC::"
18887 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018888 __func__,
18889 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18890 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018891 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018892 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018893 }
18894 }
18895 }
18896 else
18897 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018898
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018899 vos_status = hdd_softap_GetStaId(pAdapter,
18900 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018901 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18902 {
18903 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018904 "%s: Skip this DEL STA as this is not used::"
18905 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018906 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018907 return -ENOENT;
18908 }
18909
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018910 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018911 {
18912 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018913 "%s: Skip this DEL STA as deauth is in progress::"
18914 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018915 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018916 return -ENOENT;
18917 }
18918
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018919 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018920
Jeff Johnson295189b2012-06-20 16:38:30 -070018921 hddLog(VOS_TRACE_LEVEL_INFO,
18922 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018923 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018924 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018925 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018926
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018927 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018928 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18929 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018930 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018931 hddLog(VOS_TRACE_LEVEL_INFO,
18932 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018933 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018934 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018935 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018936 return -ENOENT;
18937 }
18938
Jeff Johnson295189b2012-06-20 16:38:30 -070018939 }
18940 }
18941
18942 EXIT();
18943
18944 return 0;
18945}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018946
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018947#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018948int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018949 struct net_device *dev,
18950 struct station_del_parameters *param)
18951#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018952#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018953int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018954 struct net_device *dev, const u8 *mac)
18955#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018956int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018957 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018958#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018959#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018960{
18961 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018962 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018963
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018964 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018965
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018966#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018967 if (NULL == param) {
18968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018969 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018970 return -EINVAL;
18971 }
18972
18973 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18974 param->subtype, &delStaParams);
18975
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018976#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018977 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018978 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018979#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018980 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18981
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018982 vos_ssr_unprotect(__func__);
18983
18984 return ret;
18985}
18986
18987static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018988 struct net_device *dev,
18989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18990 const u8 *mac,
18991#else
18992 u8 *mac,
18993#endif
18994 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018995{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018996 hdd_adapter_t *pAdapter;
18997 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018998 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018999#ifdef FEATURE_WLAN_TDLS
19000 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019001
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019002 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019003
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019004 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19005 if (NULL == pAdapter)
19006 {
19007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19008 "%s: Adapter is NULL",__func__);
19009 return -EINVAL;
19010 }
19011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19012 status = wlan_hdd_validate_context(pHddCtx);
19013 if (0 != status)
19014 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019015 return status;
19016 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019017
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019018 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19019 TRACE_CODE_HDD_CFG80211_ADD_STA,
19020 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019021 mask = params->sta_flags_mask;
19022
19023 set = params->sta_flags_set;
19024
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019026 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19027 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019028
19029 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19030 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019031 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019032 }
19033 }
19034#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019035 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019036 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019037}
19038
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19040static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19041 struct net_device *dev, const u8 *mac,
19042 struct station_parameters *params)
19043#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019044static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19045 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019046#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019047{
19048 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019049
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019050 vos_ssr_protect(__func__);
19051 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19052 vos_ssr_unprotect(__func__);
19053
19054 return ret;
19055}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019056#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019057
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019058static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019059 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019060{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19062 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019063 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019064 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019065 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019066 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019067
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019068 ENTER();
19069
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019070 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019071 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019072 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019074 return -EINVAL;
19075 }
19076
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019077 if (!pmksa) {
19078 hddLog(LOGE, FL("pmksa is NULL"));
19079 return -EINVAL;
19080 }
19081
19082 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019083 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019084 pmksa->bssid, pmksa->pmkid);
19085 return -EINVAL;
19086 }
19087
19088 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19089 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19090
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019091 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19092 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019093 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019095 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019096 }
19097
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019098 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019099 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19100
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019101 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19102 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019103
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019104 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019105 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019106 &pmk_id, 1, FALSE);
19107
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019108 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19109 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19110 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019112 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019113 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019114}
19115
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019116static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19117 struct cfg80211_pmksa *pmksa)
19118{
19119 int ret;
19120
19121 vos_ssr_protect(__func__);
19122 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19123 vos_ssr_unprotect(__func__);
19124
19125 return ret;
19126}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019127
Wilson Yang6507c4e2013-10-01 20:11:19 -070019128
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019129static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019130 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019131{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19133 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019134 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019135 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019137 ENTER();
19138
Wilson Yang6507c4e2013-10-01 20:11:19 -070019139 /* Validate pAdapter */
19140 if (NULL == pAdapter)
19141 {
19142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19143 return -EINVAL;
19144 }
19145
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019146 if (!pmksa) {
19147 hddLog(LOGE, FL("pmksa is NULL"));
19148 return -EINVAL;
19149 }
19150
19151 if (!pmksa->bssid) {
19152 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19153 return -EINVAL;
19154 }
19155
Kiet Lam98c46a12014-10-31 15:34:57 -070019156 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19157 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19158
Wilson Yang6507c4e2013-10-01 20:11:19 -070019159 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19160 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019161 if (0 != status)
19162 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019163 return status;
19164 }
19165
19166 /*Retrieve halHandle*/
19167 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19168
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019169 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19170 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19171 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019172 /* Delete the PMKID CSR cache */
19173 if (eHAL_STATUS_SUCCESS !=
19174 sme_RoamDelPMKIDfromCache(halHandle,
19175 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19176 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19177 MAC_ADDR_ARRAY(pmksa->bssid));
19178 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019179 }
19180
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019181 EXIT();
19182 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019183}
19184
Wilson Yang6507c4e2013-10-01 20:11:19 -070019185
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019186static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19187 struct cfg80211_pmksa *pmksa)
19188{
19189 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019190
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019191 vos_ssr_protect(__func__);
19192 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19193 vos_ssr_unprotect(__func__);
19194
19195 return ret;
19196
19197}
19198
19199static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019200{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019201 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19202 tHalHandle halHandle;
19203 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019204 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019205
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019206 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019207
19208 /* Validate pAdapter */
19209 if (NULL == pAdapter)
19210 {
19211 hddLog(VOS_TRACE_LEVEL_ERROR,
19212 "%s: Invalid Adapter" ,__func__);
19213 return -EINVAL;
19214 }
19215
19216 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19217 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019218 if (0 != status)
19219 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019220 return status;
19221 }
19222
19223 /*Retrieve halHandle*/
19224 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19225
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019226 /* Flush the PMKID cache in CSR */
19227 if (eHAL_STATUS_SUCCESS !=
19228 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19229 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19230 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019231 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019232 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019233 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019234}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019235
19236static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19237{
19238 int ret;
19239
19240 vos_ssr_protect(__func__);
19241 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19242 vos_ssr_unprotect(__func__);
19243
19244 return ret;
19245}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019246#endif
19247
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019248#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019249static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19250 struct net_device *dev,
19251 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019252{
19253 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19254 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019255 hdd_context_t *pHddCtx;
19256 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019258 ENTER();
19259
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019260 if (NULL == pAdapter)
19261 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019263 return -ENODEV;
19264 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19266 ret = wlan_hdd_validate_context(pHddCtx);
19267 if (0 != ret)
19268 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019269 return ret;
19270 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019271 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019272 if (NULL == pHddStaCtx)
19273 {
19274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19275 return -EINVAL;
19276 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019277
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019278 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19279 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19280 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019281 // Added for debug on reception of Re-assoc Req.
19282 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19283 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019284 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019285 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019286 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019287 }
19288
19289#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019290 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019291 ftie->ie_len);
19292#endif
19293
19294 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019295 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19296 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019297 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019298
19299 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019300 return 0;
19301}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019302
19303static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19304 struct net_device *dev,
19305 struct cfg80211_update_ft_ies_params *ftie)
19306{
19307 int ret;
19308
19309 vos_ssr_protect(__func__);
19310 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19311 vos_ssr_unprotect(__func__);
19312
19313 return ret;
19314}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019315#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019316
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019317#ifdef FEATURE_WLAN_SCAN_PNO
19318
19319void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19320 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19321{
19322 int ret;
19323 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19324 hdd_context_t *pHddCtx;
19325
Nirav Shah80830bf2013-12-31 16:35:12 +053019326 ENTER();
19327
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019328 if (NULL == pAdapter)
19329 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019331 "%s: HDD adapter is Null", __func__);
19332 return ;
19333 }
19334
19335 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19336 if (NULL == pHddCtx)
19337 {
19338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19339 "%s: HDD context is Null!!!", __func__);
19340 return ;
19341 }
19342
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019343 spin_lock(&pHddCtx->schedScan_lock);
19344 if (TRUE == pHddCtx->isWiphySuspended)
19345 {
19346 pHddCtx->isSchedScanUpdatePending = TRUE;
19347 spin_unlock(&pHddCtx->schedScan_lock);
19348 hddLog(VOS_TRACE_LEVEL_INFO,
19349 "%s: Update cfg80211 scan database after it resume", __func__);
19350 return ;
19351 }
19352 spin_unlock(&pHddCtx->schedScan_lock);
19353
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019354 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19355
19356 if (0 > ret)
19357 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019358 else
19359 {
19360 /* Acquire wakelock to handle the case where APP's tries to suspend
19361 * immediatly after the driver gets connect request(i.e after pno)
19362 * from supplicant, this result in app's is suspending and not able
19363 * to process the connect request to AP */
19364 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19365 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019366 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19368 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019369}
19370
19371/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019372 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019373 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019374 */
19375static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19376{
19377 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19378 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019379 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019380 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19381 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019382
19383 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19384 {
19385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19386 "%s: PNO is allowed only in STA interface", __func__);
19387 return eHAL_STATUS_FAILURE;
19388 }
19389
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019390 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19391
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019392 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019393 * active sessions. PNO is allowed only in case when sap session
19394 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019395 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019396 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19397 {
19398 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019399 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019400
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019401 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19402 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19403 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19404 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019405 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19406 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019407 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019408 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019409 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019410 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019411 }
19412 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19413 pAdapterNode = pNext;
19414 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019415 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019416}
19417
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019418void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19419{
19420 hdd_adapter_t *pAdapter = callbackContext;
19421 hdd_context_t *pHddCtx;
19422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019423 ENTER();
19424
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019425 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19426 {
19427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19428 FL("Invalid adapter or adapter has invalid magic"));
19429 return;
19430 }
19431
19432 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19433 if (0 != wlan_hdd_validate_context(pHddCtx))
19434 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019435 return;
19436 }
19437
c_hpothub53c45d2014-08-18 16:53:14 +053019438 if (VOS_STATUS_SUCCESS != status)
19439 {
19440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019441 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019442 pHddCtx->isPnoEnable = FALSE;
19443 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019444
19445 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19446 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019447 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019448}
19449
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019450#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19451 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19452/**
19453 * hdd_config_sched_scan_plan() - configures the sched scan plans
19454 * from the framework.
19455 * @pno_req: pointer to PNO scan request
19456 * @request: pointer to scan request from framework
19457 *
19458 * Return: None
19459 */
19460static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19461 struct cfg80211_sched_scan_request *request,
19462 hdd_context_t *hdd_ctx)
19463{
19464 v_U32_t i = 0;
19465
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019466 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019467 for (i = 0; i < request->n_scan_plans; i++)
19468 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019469 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19470 request->scan_plans[i].iterations;
19471 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19472 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019473 }
19474}
19475#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019476static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019477 struct cfg80211_sched_scan_request *request,
19478 hdd_context_t *hdd_ctx)
19479{
19480 v_U32_t i, temp_int;
19481 /* Driver gets only one time interval which is hardcoded in
19482 * supplicant for 10000ms. Taking power consumption into account 6
19483 * timers will be used, Timervalue is increased exponentially
19484 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19485 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19486 * If it is set to 0 only one timer will be used and PNO scan cycle
19487 * will be repeated after each interval specified by supplicant
19488 * till PNO is disabled.
19489 */
19490 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019491 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019492 HDD_PNO_SCAN_TIMERS_SET_ONE;
19493 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019494 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019495 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19496
19497 temp_int = (request->interval)/1000;
19498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19499 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19500 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019501 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019502 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019503 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019504 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019505 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019506 temp_int *= 2;
19507 }
19508 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019509 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019510}
19511#endif
19512
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019513/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019514 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19515 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019516 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019517static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019518 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19519{
19520 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019521 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019522 hdd_context_t *pHddCtx;
19523 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019524 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019525 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19526 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019527 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19528 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019529 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019530 hdd_config_t *pConfig = NULL;
19531 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019533 ENTER();
19534
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019535 if (NULL == pAdapter)
19536 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019538 "%s: HDD adapter is Null", __func__);
19539 return -ENODEV;
19540 }
19541
19542 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019543 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019544
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019545 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019546 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019547 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019548 }
19549
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019550 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019551 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19552 if (NULL == hHal)
19553 {
19554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19555 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019556 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019557 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019558 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19559 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19560 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019561 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019562 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019563 {
19564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19565 "%s: aborting the existing scan is unsuccessfull", __func__);
19566 return -EBUSY;
19567 }
19568
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019569 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019570 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019572 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019573 return -EBUSY;
19574 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019575
c_hpothu37f21312014-04-09 21:49:54 +053019576 if (TRUE == pHddCtx->isPnoEnable)
19577 {
19578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19579 FL("already PNO is enabled"));
19580 return -EBUSY;
19581 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019582
19583 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19584 {
19585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19586 "%s: abort ROC failed ", __func__);
19587 return -EBUSY;
19588 }
19589
c_hpothu37f21312014-04-09 21:49:54 +053019590 pHddCtx->isPnoEnable = TRUE;
19591
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019592 pnoRequest.enable = 1; /*Enable PNO */
19593 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019594
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019595 if (( !pnoRequest.ucNetworksCount ) ||
19596 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019597 {
19598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019599 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019600 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019601 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019602 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019603 goto error;
19604 }
19605
19606 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19607 {
19608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019609 "%s: Incorrect number of channels %d",
19610 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019611 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019612 goto error;
19613 }
19614
19615 /* Framework provides one set of channels(all)
19616 * common for all saved profile */
19617 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19618 channels_allowed, &num_channels_allowed))
19619 {
19620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19621 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019622 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019623 goto error;
19624 }
19625 /* Checking each channel against allowed channel list */
19626 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019627 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019628 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019629 char chList [(request->n_channels*5)+1];
19630 int len;
19631 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019632 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019633 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019634 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019635 if (request->channels[i]->hw_value == channels_allowed[indx])
19636 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019637 if ((!pConfig->enableDFSPnoChnlScan) &&
19638 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19639 {
19640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19641 "%s : Dropping DFS channel : %d",
19642 __func__,channels_allowed[indx]);
19643 num_ignore_dfs_ch++;
19644 break;
19645 }
19646
Nirav Shah80830bf2013-12-31 16:35:12 +053019647 valid_ch[num_ch++] = request->channels[i]->hw_value;
19648 len += snprintf(chList+len, 5, "%d ",
19649 request->channels[i]->hw_value);
19650 break ;
19651 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019652 }
19653 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019654 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019655
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019656 /*If all channels are DFS and dropped, then ignore the PNO request*/
19657 if (num_ignore_dfs_ch == request->n_channels)
19658 {
19659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19660 "%s : All requested channels are DFS channels", __func__);
19661 ret = -EINVAL;
19662 goto error;
19663 }
19664 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019665
19666 pnoRequest.aNetworks =
19667 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19668 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019669 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019670 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19671 FL("failed to allocate memory aNetworks %u"),
19672 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19673 goto error;
19674 }
19675 vos_mem_zero(pnoRequest.aNetworks,
19676 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19677
19678 /* Filling per profile params */
19679 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19680 {
19681 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019682 request->match_sets[i].ssid.ssid_len;
19683
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019684 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19685 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019686 {
19687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019688 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019689 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019690 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019691 goto error;
19692 }
19693
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019694 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019695 request->match_sets[i].ssid.ssid,
19696 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19698 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019699 i, pnoRequest.aNetworks[i].ssId.ssId);
19700 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19701 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19702 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019703
19704 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019705 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19706 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019707
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019708 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019709 }
19710
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019711 for (i = 0; i < request->n_ssids; i++)
19712 {
19713 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019714 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019715 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019716 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019717 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019718 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019719 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019720 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019721 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019722 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019723 break;
19724 }
19725 j++;
19726 }
19727 }
19728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19729 "Number of hidden networks being Configured = %d",
19730 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019732 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019733
19734 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19735 if (pnoRequest.p24GProbeTemplate == NULL)
19736 {
19737 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19738 FL("failed to allocate memory p24GProbeTemplate %u"),
19739 SIR_PNO_MAX_PB_REQ_SIZE);
19740 goto error;
19741 }
19742
19743 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19744 if (pnoRequest.p5GProbeTemplate == NULL)
19745 {
19746 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19747 FL("failed to allocate memory p5GProbeTemplate %u"),
19748 SIR_PNO_MAX_PB_REQ_SIZE);
19749 goto error;
19750 }
19751
19752 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19753 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19754
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019755 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19756 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019757 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019758 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19759 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19760 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019761
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019762 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19763 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19764 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019765 }
19766
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019767 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019768
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019769 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019770
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019771 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019772 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19773 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019774 pAdapter->pno_req_status = 0;
19775
Nirav Shah80830bf2013-12-31 16:35:12 +053019776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19777 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019778 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19779 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019780
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019781 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019782 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019783 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19784 if (eHAL_STATUS_SUCCESS != status)
19785 {
19786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019787 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019788 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019789 goto error;
19790 }
19791
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019792 ret = wait_for_completion_timeout(
19793 &pAdapter->pno_comp_var,
19794 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19795 if (0 >= ret)
19796 {
19797 // Did not receive the response for PNO enable in time.
19798 // Assuming the PNO enable was success.
19799 // Returning error from here, because we timeout, results
19800 // in side effect of Wifi (Wifi Setting) not to work.
19801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19802 FL("Timed out waiting for PNO to be Enabled"));
19803 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019804 }
19805
19806 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019807 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019808
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019809error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19811 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019812 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019813 if (pnoRequest.aNetworks)
19814 vos_mem_free(pnoRequest.aNetworks);
19815 if (pnoRequest.p24GProbeTemplate)
19816 vos_mem_free(pnoRequest.p24GProbeTemplate);
19817 if (pnoRequest.p5GProbeTemplate)
19818 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019819
19820 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019821 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019822}
19823
19824/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019825 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19826 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019827 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019828static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19829 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19830{
19831 int ret;
19832
19833 vos_ssr_protect(__func__);
19834 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19835 vos_ssr_unprotect(__func__);
19836
19837 return ret;
19838}
19839
19840/*
19841 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19842 * Function to disable PNO
19843 */
19844static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019845 struct net_device *dev)
19846{
19847 eHalStatus status = eHAL_STATUS_FAILURE;
19848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19849 hdd_context_t *pHddCtx;
19850 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019851 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019852 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019853
19854 ENTER();
19855
19856 if (NULL == pAdapter)
19857 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019859 "%s: HDD adapter is Null", __func__);
19860 return -ENODEV;
19861 }
19862
19863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019864
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019865 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019866 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019868 "%s: HDD context is Null", __func__);
19869 return -ENODEV;
19870 }
19871
19872 /* The return 0 is intentional when isLogpInProgress and
19873 * isLoadUnloadInProgress. We did observe a crash due to a return of
19874 * failure in sched_scan_stop , especially for a case where the unload
19875 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19876 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19877 * success. If it returns a failure , then its next invocation due to the
19878 * clean up of the second interface will have the dev pointer corresponding
19879 * to the first one leading to a crash.
19880 */
19881 if (pHddCtx->isLogpInProgress)
19882 {
19883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19884 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019885 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019886 return ret;
19887 }
19888
Mihir Shete18156292014-03-11 15:38:30 +053019889 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019890 {
19891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19892 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19893 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019894 }
19895
19896 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19897 if (NULL == hHal)
19898 {
19899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19900 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019901 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019902 }
19903
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019904 pnoRequest.enable = 0; /* Disable PNO */
19905 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019906
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19908 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19909 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019910
19911 INIT_COMPLETION(pAdapter->pno_comp_var);
19912 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19913 pnoRequest.callbackContext = pAdapter;
19914 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019915 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019916 pAdapter->sessionId,
19917 NULL, pAdapter);
19918 if (eHAL_STATUS_SUCCESS != status)
19919 {
19920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19921 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019922 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019923 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019924 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019925 ret = wait_for_completion_timeout(
19926 &pAdapter->pno_comp_var,
19927 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19928 if (0 >= ret)
19929 {
19930 // Did not receive the response for PNO disable in time.
19931 // Assuming the PNO disable was success.
19932 // Returning error from here, because we timeout, results
19933 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019935 FL("Timed out waiting for PNO to be disabled"));
19936 ret = 0;
19937 }
19938
19939 ret = pAdapter->pno_req_status;
19940 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019941
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019942error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019944 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019945
19946 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019947 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019948}
19949
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019950/*
19951 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19952 * NL interface to disable PNO
19953 */
19954static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19955 struct net_device *dev)
19956{
19957 int ret;
19958
19959 vos_ssr_protect(__func__);
19960 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19961 vos_ssr_unprotect(__func__);
19962
19963 return ret;
19964}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019965#endif /*FEATURE_WLAN_SCAN_PNO*/
19966
19967
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019968#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019969#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019970static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19971 struct net_device *dev,
19972 u8 *peer, u8 action_code,
19973 u8 dialog_token,
19974 u16 status_code, u32 peer_capability,
19975 const u8 *buf, size_t len)
19976#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019977#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19978 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019979static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19980 struct net_device *dev,
19981 const u8 *peer, u8 action_code,
19982 u8 dialog_token, u16 status_code,
19983 u32 peer_capability, bool initiator,
19984 const u8 *buf, size_t len)
19985#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19986static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19987 struct net_device *dev,
19988 const u8 *peer, u8 action_code,
19989 u8 dialog_token, u16 status_code,
19990 u32 peer_capability, const u8 *buf,
19991 size_t len)
19992#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19993static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19994 struct net_device *dev,
19995 u8 *peer, u8 action_code,
19996 u8 dialog_token,
19997 u16 status_code, u32 peer_capability,
19998 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019999#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020000static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20001 struct net_device *dev,
20002 u8 *peer, u8 action_code,
20003 u8 dialog_token,
20004 u16 status_code, const u8 *buf,
20005 size_t len)
20006#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020007#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020008{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020009 hdd_adapter_t *pAdapter;
20010 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020011 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020012 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020013 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020014 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020015 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020016 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020017#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020018 u32 peer_capability = 0;
20019#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020020 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020021 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020022 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020023
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020024 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20025 if (NULL == pAdapter)
20026 {
20027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20028 "%s: Adapter is NULL",__func__);
20029 return -EINVAL;
20030 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020031 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20032 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20033 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020034
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020035 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020036 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020039 "Invalid arguments");
20040 return -EINVAL;
20041 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020042
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020043 if (pHddCtx->isLogpInProgress)
20044 {
20045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20046 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020047 wlan_hdd_tdls_set_link_status(pAdapter,
20048 peer,
20049 eTDLS_LINK_IDLE,
20050 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020051 return -EBUSY;
20052 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020053
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020054 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20055 {
20056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20057 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20058 return -EAGAIN;
20059 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020060
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020061 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20062 if (!pHddTdlsCtx) {
20063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20064 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020065 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020066 }
20067
Hoonki Lee27511902013-03-14 18:19:06 -070020068 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020069 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020071 "%s: TDLS mode is disabled OR not enabled in FW."
20072 MAC_ADDRESS_STR " action %d declined.",
20073 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020074 return -ENOTSUPP;
20075 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020076
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020077 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20078
20079 if( NULL == pHddStaCtx )
20080 {
20081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20082 "%s: HDD station context NULL ",__func__);
20083 return -EINVAL;
20084 }
20085
20086 /* STA should be connected and authenticated
20087 * before sending any TDLS frames
20088 */
20089 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20090 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20091 {
20092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20093 "STA is not connected or unauthenticated. "
20094 "connState %u, uIsAuthenticated %u",
20095 pHddStaCtx->conn_info.connState,
20096 pHddStaCtx->conn_info.uIsAuthenticated);
20097 return -EAGAIN;
20098 }
20099
Hoonki Lee27511902013-03-14 18:19:06 -070020100 /* other than teardown frame, other mgmt frames are not sent if disabled */
20101 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20102 {
20103 /* if tdls_mode is disabled to respond to peer's request */
20104 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20105 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020107 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020108 " TDLS mode is disabled. action %d declined.",
20109 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020110
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020111 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020112 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020113
20114 if (vos_max_concurrent_connections_reached())
20115 {
20116 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20117 return -EINVAL;
20118 }
Hoonki Lee27511902013-03-14 18:19:06 -070020119 }
20120
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020121 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20122 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020123 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020124 {
20125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020126 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020127 " TDLS setup is ongoing. action %d declined.",
20128 __func__, MAC_ADDR_ARRAY(peer), action_code);
20129 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020130 }
20131 }
20132
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020133 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20134 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020135 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020136 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20137 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020138 {
20139 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20140 we return error code at 'add_station()'. Hence we have this
20141 check again in addtion to add_station().
20142 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020143 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020144 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20146 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020147 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20148 __func__, MAC_ADDR_ARRAY(peer), action_code,
20149 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020150 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020151 }
20152 else
20153 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020154 /* maximum reached. tweak to send error code to peer and return
20155 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020156 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20158 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020159 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20160 __func__, MAC_ADDR_ARRAY(peer), status_code,
20161 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020162 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020163 /* fall through to send setup resp with failure status
20164 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020165 }
20166 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020167 else
20168 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020169 mutex_lock(&pHddCtx->tdls_lock);
20170 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020171 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020172 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020173 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020175 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20176 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020177 return -EPERM;
20178 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020179 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020180 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020181 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020182
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020184 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020185 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20186 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020187
Hoonki Leea34dd892013-02-05 22:56:02 -080020188 /*Except teardown responder will not be used so just make 0*/
20189 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020190 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020191 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020192
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020193 mutex_lock(&pHddCtx->tdls_lock);
20194 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020195
20196 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20197 responder = pTdlsPeer->is_responder;
20198 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020199 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020201 "%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 -070020202 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20203 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020204 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020205 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020206 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020207 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020208 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020209
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020210 /* Discard TDLS setup if peer is removed by user app */
20211 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20212 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20213 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20214 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20215
20216 mutex_lock(&pHddCtx->tdls_lock);
20217 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20218 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20219 mutex_unlock(&pHddCtx->tdls_lock);
20220 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20221 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20222 MAC_ADDR_ARRAY(peer), action_code);
20223 return -EINVAL;
20224 }
20225 mutex_unlock(&pHddCtx->tdls_lock);
20226 }
20227
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020228 /* For explicit trigger of DIS_REQ come out of BMPS for
20229 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020230 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020231 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020232 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20233 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020234 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020235 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020237 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20238 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020239 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20240 if (status != VOS_STATUS_SUCCESS) {
20241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020242 } else {
20243 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020244 }
Hoonki Lee14621352013-04-16 17:51:19 -070020245 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020246 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020247 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20249 }
20250 }
Hoonki Lee14621352013-04-16 17:51:19 -070020251 }
20252
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020253 /* make sure doesn't call send_mgmt() while it is pending */
20254 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20255 {
20256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020257 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020258 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020259 ret = -EBUSY;
20260 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020261 }
20262
20263 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020264 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20265
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020266 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20267 pAdapter->sessionId, peer, action_code, dialog_token,
20268 status_code, peer_capability, (tANI_U8 *)buf, len,
20269 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020270
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020271 if (VOS_STATUS_SUCCESS != status)
20272 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20274 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020275 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020276 ret = -EINVAL;
20277 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020278 }
20279
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20281 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20282 WAIT_TIME_TDLS_MGMT);
20283
Hoonki Leed37cbb32013-04-20 00:31:14 -070020284 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20285 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20286
20287 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020288 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020290 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020291 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020292 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020293
20294 if (pHddCtx->isLogpInProgress)
20295 {
20296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20297 "%s: LOGP in Progress. Ignore!!!", __func__);
20298 return -EAGAIN;
20299 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020300 if (rc <= 0)
20301 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20302 WLAN_LOG_INDICATOR_HOST_DRIVER,
20303 WLAN_LOG_REASON_HDD_TIME_OUT,
20304 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020305
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020306 ret = -EINVAL;
20307 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020308 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020309 else
20310 {
20311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20312 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20313 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20314 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020315
Gopichand Nakkala05922802013-03-14 12:23:19 -070020316 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020317 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020318 ret = max_sta_failed;
20319 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020320 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020321
Hoonki Leea34dd892013-02-05 22:56:02 -080020322 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20323 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020324 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20326 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020327 }
20328 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20329 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020330 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20332 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020333 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020334
20335 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020336
20337tx_failed:
20338 /* add_station will be called before sending TDLS_SETUP_REQ and
20339 * TDLS_SETUP_RSP and as part of add_station driver will enable
20340 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20341 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20342 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20343 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20344 */
20345
20346 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20347 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20348 wlan_hdd_tdls_check_bmps(pAdapter);
20349 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020350}
20351
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020352#if TDLS_MGMT_VERSION2
20353static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20354 u8 *peer, u8 action_code, u8 dialog_token,
20355 u16 status_code, u32 peer_capability,
20356 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020357#else /* TDLS_MGMT_VERSION2 */
20358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20359static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20360 struct net_device *dev,
20361 const u8 *peer, u8 action_code,
20362 u8 dialog_token, u16 status_code,
20363 u32 peer_capability, bool initiator,
20364 const u8 *buf, size_t len)
20365#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20366static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20367 struct net_device *dev,
20368 const u8 *peer, u8 action_code,
20369 u8 dialog_token, u16 status_code,
20370 u32 peer_capability, const u8 *buf,
20371 size_t len)
20372#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20373static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20374 struct net_device *dev,
20375 u8 *peer, u8 action_code,
20376 u8 dialog_token,
20377 u16 status_code, u32 peer_capability,
20378 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020379#else
20380static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20381 u8 *peer, u8 action_code, u8 dialog_token,
20382 u16 status_code, const u8 *buf, size_t len)
20383#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020384#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020385{
20386 int ret;
20387
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020388 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020389#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020390 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20391 dialog_token, status_code,
20392 peer_capability, buf, len);
20393#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020394#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20395 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020396 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20397 dialog_token, status_code,
20398 peer_capability, initiator,
20399 buf, len);
20400#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20401 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20402 dialog_token, status_code,
20403 peer_capability, buf, len);
20404#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20405 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20406 dialog_token, status_code,
20407 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020408#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020409 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20410 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020411#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020412#endif
20413 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020414
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020415 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020416}
Atul Mittal115287b2014-07-08 13:26:33 +053020417
20418int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020419#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20420 const u8 *peer,
20421#else
Atul Mittal115287b2014-07-08 13:26:33 +053020422 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020423#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020424 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020425 cfg80211_exttdls_callback callback)
20426{
20427
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020428 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020429 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020430 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20432 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20433 __func__, MAC_ADDR_ARRAY(peer));
20434
20435 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20436 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20437
20438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020439 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20440 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20441 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020442 return -ENOTSUPP;
20443 }
20444
20445 /* To cater the requirement of establishing the TDLS link
20446 * irrespective of the data traffic , get an entry of TDLS peer.
20447 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020448 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020449 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20450 if (pTdlsPeer == NULL) {
20451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20452 "%s: peer " MAC_ADDRESS_STR " not existing",
20453 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020454 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020455 return -EINVAL;
20456 }
20457
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020458 /* check FW TDLS Off Channel capability */
20459 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020460 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020461 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020462 {
20463 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20464 pTdlsPeer->peerParams.global_operating_class =
20465 tdls_peer_params->global_operating_class;
20466 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20467 pTdlsPeer->peerParams.min_bandwidth_kbps =
20468 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020469 /* check configured channel is valid, non dfs and
20470 * not current operating channel */
20471 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20472 tdls_peer_params->channel)) &&
20473 (pHddStaCtx) &&
20474 (tdls_peer_params->channel !=
20475 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020476 {
20477 pTdlsPeer->isOffChannelConfigured = TRUE;
20478 }
20479 else
20480 {
20481 pTdlsPeer->isOffChannelConfigured = FALSE;
20482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20483 "%s: Configured Tdls Off Channel is not valid", __func__);
20484
20485 }
20486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020487 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20488 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020489 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020490 pTdlsPeer->isOffChannelConfigured,
20491 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020492 }
20493 else
20494 {
20495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020496 "%s: TDLS off channel FW capability %d, "
20497 "host capab %d or Invalid TDLS Peer Params", __func__,
20498 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20499 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020500 }
20501
Atul Mittal115287b2014-07-08 13:26:33 +053020502 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20503
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020504 mutex_unlock(&pHddCtx->tdls_lock);
20505
Atul Mittal115287b2014-07-08 13:26:33 +053020506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20507 " %s TDLS Add Force Peer Failed",
20508 __func__);
20509 return -EINVAL;
20510 }
20511 /*EXT TDLS*/
20512
20513 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020514 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20516 " %s TDLS set callback Failed",
20517 __func__);
20518 return -EINVAL;
20519 }
20520
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020521 mutex_unlock(&pHddCtx->tdls_lock);
20522
Atul Mittal115287b2014-07-08 13:26:33 +053020523 return(0);
20524
20525}
20526
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020527int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20528#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20529 const u8 *peer
20530#else
20531 u8 *peer
20532#endif
20533)
Atul Mittal115287b2014-07-08 13:26:33 +053020534{
20535
20536 hddTdlsPeer_t *pTdlsPeer;
20537 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020538
Atul Mittal115287b2014-07-08 13:26:33 +053020539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20540 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20541 __func__, MAC_ADDR_ARRAY(peer));
20542
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020543 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20544 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20545 return -EINVAL;
20546 }
20547
Atul Mittal115287b2014-07-08 13:26:33 +053020548 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20549 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20550
20551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020552 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20553 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20554 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020555 return -ENOTSUPP;
20556 }
20557
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020558 mutex_lock(&pHddCtx->tdls_lock);
20559 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020560
20561 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020562 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020563 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020564 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020565 __func__, MAC_ADDR_ARRAY(peer));
20566 return -EINVAL;
20567 }
20568 else {
20569 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20570 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020571 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20572 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020573 /* if channel switch is configured, reset
20574 the channel for this peer */
20575 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20576 {
20577 pTdlsPeer->peerParams.channel = 0;
20578 pTdlsPeer->isOffChannelConfigured = FALSE;
20579 }
Atul Mittal115287b2014-07-08 13:26:33 +053020580 }
20581
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020582 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020583 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020585 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020586 }
Atul Mittal115287b2014-07-08 13:26:33 +053020587
20588 /*EXT TDLS*/
20589
20590 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020591 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20593 " %s TDLS set callback Failed",
20594 __func__);
20595 return -EINVAL;
20596 }
Atul Mittal115287b2014-07-08 13:26:33 +053020597
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020598 mutex_unlock(&pHddCtx->tdls_lock);
20599
20600 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020601}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020602static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20604 const u8 *peer,
20605#else
20606 u8 *peer,
20607#endif
20608 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020609{
20610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20611 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020612 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020613 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020615 ENTER();
20616
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020617 if (!pAdapter) {
20618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20619 return -EINVAL;
20620 }
20621
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20623 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20624 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020625 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020626 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020628 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020629 return -EINVAL;
20630 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020631
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020632 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020633 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020635 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020636 }
20637
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020638
20639 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020640 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020641 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020643 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20644 "Cannot process TDLS commands",
20645 pHddCtx->cfg_ini->fEnableTDLSSupport,
20646 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020647 return -ENOTSUPP;
20648 }
20649
20650 switch (oper) {
20651 case NL80211_TDLS_ENABLE_LINK:
20652 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020653 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020654 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020655 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20656 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020657 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020658 tANI_U16 numCurrTdlsPeers = 0;
20659 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020660 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020661 tSirMacAddr peerMac;
20662 int channel;
20663 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020664
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20666 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20667 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020668
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020669 mutex_lock(&pHddCtx->tdls_lock);
20670 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020671 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020672 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020673 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20675 " (oper %d) not exsting. ignored",
20676 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20677 return -EINVAL;
20678 }
20679
20680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20681 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20682 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20683 "NL80211_TDLS_ENABLE_LINK");
20684
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020685 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20686 {
20687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20688 MAC_ADDRESS_STR " failed",
20689 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020690 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020691 return -EINVAL;
20692 }
20693
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020694 /* before starting tdls connection, set tdls
20695 * off channel established status to default value */
20696 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020697
20698 mutex_unlock(&pHddCtx->tdls_lock);
20699
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020700 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020701 /* TDLS Off Channel, Disable tdls channel switch,
20702 when there are more than one tdls link */
20703 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020704 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020705 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020706 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020707 /* get connected peer and send disable tdls off chan */
20708 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020709 if ((connPeer) &&
20710 (connPeer->isOffChannelSupported == TRUE) &&
20711 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020712 {
20713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20714 "%s: More then one peer connected, Disable "
20715 "TDLS channel switch", __func__);
20716
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020717 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020718 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20719 channel = connPeer->peerParams.channel;
20720
20721 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020722
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020723 ret = sme_SendTdlsChanSwitchReq(
20724 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020725 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020726 peerMac,
20727 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020728 TDLS_OFF_CHANNEL_BW_OFFSET,
20729 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020730 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020731 hddLog(VOS_TRACE_LEVEL_ERROR,
20732 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020733 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020734 }
20735 else
20736 {
20737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20738 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020739 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020740 "isOffChannelConfigured %d",
20741 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020742 (connPeer ? (connPeer->isOffChannelSupported)
20743 : -1),
20744 (connPeer ? (connPeer->isOffChannelConfigured)
20745 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020746 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020747 }
20748 }
20749
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020750 mutex_lock(&pHddCtx->tdls_lock);
20751 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20752 if ( NULL == pTdlsPeer ) {
20753 mutex_unlock(&pHddCtx->tdls_lock);
20754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20755 "%s: " MAC_ADDRESS_STR
20756 " (oper %d) peer got freed in other context. ignored",
20757 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20758 return -EINVAL;
20759 }
20760 peer_status = pTdlsPeer->link_status;
20761 mutex_unlock(&pHddCtx->tdls_lock);
20762
20763 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020764 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020765 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020766
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020767 if (0 != wlan_hdd_tdls_get_link_establish_params(
20768 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020770 return -EINVAL;
20771 }
20772 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020773
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020774 ret = sme_SendTdlsLinkEstablishParams(
20775 WLAN_HDD_GET_HAL_CTX(pAdapter),
20776 pAdapter->sessionId, peer,
20777 &tdlsLinkEstablishParams);
20778 if (ret != VOS_STATUS_SUCCESS) {
20779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20780 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020781 /* Send TDLS peer UAPSD capabilities to the firmware and
20782 * register with the TL on after the response for this operation
20783 * is received .
20784 */
20785 ret = wait_for_completion_interruptible_timeout(
20786 &pAdapter->tdls_link_establish_req_comp,
20787 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020788
20789 mutex_lock(&pHddCtx->tdls_lock);
20790 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20791 if ( NULL == pTdlsPeer ) {
20792 mutex_unlock(&pHddCtx->tdls_lock);
20793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20794 "%s %d: " MAC_ADDRESS_STR
20795 " (oper %d) peer got freed in other context. ignored",
20796 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20797 (int)oper);
20798 return -EINVAL;
20799 }
20800 peer_status = pTdlsPeer->link_status;
20801 mutex_unlock(&pHddCtx->tdls_lock);
20802
20803 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020804 {
20805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020806 FL("Link Establish Request Failed Status %ld"),
20807 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020808 return -EINVAL;
20809 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020810 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020811
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020812 mutex_lock(&pHddCtx->tdls_lock);
20813 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20814 if ( NULL == pTdlsPeer ) {
20815 mutex_unlock(&pHddCtx->tdls_lock);
20816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20817 "%s: " MAC_ADDRESS_STR
20818 " (oper %d) peer got freed in other context. ignored",
20819 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20820 return -EINVAL;
20821 }
20822
Atul Mittal115287b2014-07-08 13:26:33 +053020823 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20824 eTDLS_LINK_CONNECTED,
20825 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020826 staDesc.ucSTAId = pTdlsPeer->staId;
20827 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020828
20829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20830 "%s: tdlsLinkEstablishParams of peer "
20831 MAC_ADDRESS_STR "uapsdQueues: %d"
20832 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20833 "isResponder: %d peerstaId: %d",
20834 __func__,
20835 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20836 tdlsLinkEstablishParams.uapsdQueues,
20837 tdlsLinkEstablishParams.qos,
20838 tdlsLinkEstablishParams.maxSp,
20839 tdlsLinkEstablishParams.isBufSta,
20840 tdlsLinkEstablishParams.isOffChannelSupported,
20841 tdlsLinkEstablishParams.isResponder,
20842 pTdlsPeer->staId);
20843
20844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20845 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20846 __func__,
20847 staDesc.ucSTAId,
20848 staDesc.ucQosEnabled);
20849
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020850 ret = WLANTL_UpdateTdlsSTAClient(
20851 pHddCtx->pvosContext,
20852 &staDesc);
20853 if (ret != VOS_STATUS_SUCCESS) {
20854 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20855 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020856
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020857 /* Mark TDLS client Authenticated .*/
20858 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20859 pTdlsPeer->staId,
20860 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020861 if (VOS_STATUS_SUCCESS == status)
20862 {
Hoonki Lee14621352013-04-16 17:51:19 -070020863 if (pTdlsPeer->is_responder == 0)
20864 {
20865 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020866 tdlsConnInfo_t *tdlsInfo;
20867
20868 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20869
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020870 if (!vos_timer_is_initialized(
20871 &pTdlsPeer->initiatorWaitTimeoutTimer))
20872 {
20873 /* Initialize initiator wait callback */
20874 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020875 &pTdlsPeer->initiatorWaitTimeoutTimer,
20876 VOS_TIMER_TYPE_SW,
20877 wlan_hdd_tdls_initiator_wait_cb,
20878 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020879 }
Hoonki Lee14621352013-04-16 17:51:19 -070020880 wlan_hdd_tdls_timer_restart(pAdapter,
20881 &pTdlsPeer->initiatorWaitTimeoutTimer,
20882 WAIT_TIME_TDLS_INITIATOR);
20883 /* suspend initiator TX until it receives direct packet from the
20884 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020885 ret = WLANTL_SuspendDataTx(
20886 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20887 &staId, NULL);
20888 if (ret != VOS_STATUS_SUCCESS) {
20889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20890 }
Hoonki Lee14621352013-04-16 17:51:19 -070020891 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020892
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020893 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020894 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020895 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020896 suppChannelLen =
20897 tdlsLinkEstablishParams.supportedChannelsLen;
20898
20899 if ((suppChannelLen > 0) &&
20900 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20901 {
20902 tANI_U8 suppPeerChannel = 0;
20903 int i = 0;
20904 for (i = 0U; i < suppChannelLen; i++)
20905 {
20906 suppPeerChannel =
20907 tdlsLinkEstablishParams.supportedChannels[i];
20908
20909 pTdlsPeer->isOffChannelSupported = FALSE;
20910 if (suppPeerChannel ==
20911 pTdlsPeer->peerParams.channel)
20912 {
20913 pTdlsPeer->isOffChannelSupported = TRUE;
20914 break;
20915 }
20916 }
20917 }
20918 else
20919 {
20920 pTdlsPeer->isOffChannelSupported = FALSE;
20921 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020922 }
20923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20924 "%s: TDLS channel switch request for channel "
20925 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020926 "%d isOffChannelSupported %d", __func__,
20927 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020928 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020929 suppChannelLen,
20930 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020931
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020932 /* TDLS Off Channel, Enable tdls channel switch,
20933 when their is only one tdls link and it supports */
20934 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20935 if ((numCurrTdlsPeers == 1) &&
20936 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20937 (TRUE == pTdlsPeer->isOffChannelConfigured))
20938 {
20939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20940 "%s: Send TDLS channel switch request for channel %d",
20941 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020942
20943 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020944 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20945 channel = pTdlsPeer->peerParams.channel;
20946
20947 mutex_unlock(&pHddCtx->tdls_lock);
20948
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020949 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20950 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020951 peerMac,
20952 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020953 TDLS_OFF_CHANNEL_BW_OFFSET,
20954 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020955 if (ret != VOS_STATUS_SUCCESS) {
20956 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20957 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020958 }
20959 else
20960 {
20961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20962 "%s: TDLS channel switch request not sent"
20963 " numCurrTdlsPeers %d "
20964 "isOffChannelSupported %d "
20965 "isOffChannelConfigured %d",
20966 __func__, numCurrTdlsPeers,
20967 pTdlsPeer->isOffChannelSupported,
20968 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020969 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020970 }
20971
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020972 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020973 else
20974 mutex_unlock(&pHddCtx->tdls_lock);
20975
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020976 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020977
20978 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020979 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20980 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020981 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020982 int ac;
20983 uint8 ucAc[4] = { WLANTL_AC_VO,
20984 WLANTL_AC_VI,
20985 WLANTL_AC_BK,
20986 WLANTL_AC_BE };
20987 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20988 for(ac=0; ac < 4; ac++)
20989 {
20990 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20991 pTdlsPeer->staId, ucAc[ac],
20992 tlTid[ac], tlTid[ac], 0, 0,
20993 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020994 if (status != VOS_STATUS_SUCCESS) {
20995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20996 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020997 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020998 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020999 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021000
Bhargav Shah66896792015-10-01 18:17:37 +053021001 /* stop TCP delack timer if TDLS is enable */
21002 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21003 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021004 hdd_wlan_tdls_enable_link_event(peer,
21005 pTdlsPeer->isOffChannelSupported,
21006 pTdlsPeer->isOffChannelConfigured,
21007 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021008 }
21009 break;
21010 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021011 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021012 tANI_U16 numCurrTdlsPeers = 0;
21013 hddTdlsPeer_t *connPeer = NULL;
21014
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21016 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21017 __func__, MAC_ADDR_ARRAY(peer));
21018
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021019 mutex_lock(&pHddCtx->tdls_lock);
21020 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021021
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021022
Sunil Dutt41de4e22013-11-14 18:09:02 +053021023 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021024 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21026 " (oper %d) not exsting. ignored",
21027 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21028 return -EINVAL;
21029 }
21030
21031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21032 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21033 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21034 "NL80211_TDLS_DISABLE_LINK");
21035
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021036 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021037 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021038 long status;
21039
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021040 /* set tdls off channel status to false for this peer */
21041 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021042 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21043 eTDLS_LINK_TEARING,
21044 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21045 eTDLS_LINK_UNSPECIFIED:
21046 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021047 mutex_unlock(&pHddCtx->tdls_lock);
21048
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021049 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21050
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021051 status = sme_DeleteTdlsPeerSta(
21052 WLAN_HDD_GET_HAL_CTX(pAdapter),
21053 pAdapter->sessionId, peer );
21054 if (status != VOS_STATUS_SUCCESS) {
21055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21056 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021057
21058 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21059 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021060
21061 mutex_lock(&pHddCtx->tdls_lock);
21062 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21063 if ( NULL == pTdlsPeer ) {
21064 mutex_unlock(&pHddCtx->tdls_lock);
21065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21066 " peer was freed in other context",
21067 __func__, MAC_ADDR_ARRAY(peer));
21068 return -EINVAL;
21069 }
21070
Atul Mittal271a7652014-09-12 13:18:22 +053021071 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021072 eTDLS_LINK_IDLE,
21073 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021074 mutex_unlock(&pHddCtx->tdls_lock);
21075
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021076 if (status <= 0)
21077 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21079 "%s: Del station failed status %ld",
21080 __func__, status);
21081 return -EPERM;
21082 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021083
21084 /* TDLS Off Channel, Enable tdls channel switch,
21085 when their is only one tdls link and it supports */
21086 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21087 if (numCurrTdlsPeers == 1)
21088 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021089 tSirMacAddr peerMac;
21090 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021091
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021092 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021093 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021094
21095 if (connPeer == NULL) {
21096 mutex_unlock(&pHddCtx->tdls_lock);
21097 hddLog(VOS_TRACE_LEVEL_ERROR,
21098 "%s connPeer is NULL", __func__);
21099 return -EINVAL;
21100 }
21101
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021102 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21103 channel = connPeer->peerParams.channel;
21104
21105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21106 "%s: TDLS channel switch "
21107 "isOffChannelSupported %d "
21108 "isOffChannelConfigured %d "
21109 "isOffChannelEstablished %d",
21110 __func__,
21111 (connPeer ? connPeer->isOffChannelSupported : -1),
21112 (connPeer ? connPeer->isOffChannelConfigured : -1),
21113 (connPeer ? connPeer->isOffChannelEstablished : -1));
21114
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021115 if ((connPeer) &&
21116 (connPeer->isOffChannelSupported == TRUE) &&
21117 (connPeer->isOffChannelConfigured == TRUE))
21118 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021119 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021120 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021121 status = sme_SendTdlsChanSwitchReq(
21122 WLAN_HDD_GET_HAL_CTX(pAdapter),
21123 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021124 peerMac,
21125 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021126 TDLS_OFF_CHANNEL_BW_OFFSET,
21127 TDLS_CHANNEL_SWITCH_ENABLE);
21128 if (status != VOS_STATUS_SUCCESS) {
21129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21130 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021131 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021132 else
21133 mutex_unlock(&pHddCtx->tdls_lock);
21134 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021135 else
21136 {
21137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21138 "%s: TDLS channel switch request not sent "
21139 "numCurrTdlsPeers %d ",
21140 __func__, numCurrTdlsPeers);
21141 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021142 }
21143 else
21144 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021145 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21147 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021148 }
Bhargav Shah66896792015-10-01 18:17:37 +053021149 if (numCurrTdlsPeers == 0) {
21150 /* start TCP delack timer if TDLS is disable */
21151 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21152 hdd_manage_delack_timer(pHddCtx);
21153 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021154 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021155 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021156 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021157 {
Atul Mittal115287b2014-07-08 13:26:33 +053021158 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021159
Atul Mittal115287b2014-07-08 13:26:33 +053021160 if (0 != status)
21161 {
21162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021163 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021164 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021165 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021166 break;
21167 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021168 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021169 {
Atul Mittal115287b2014-07-08 13:26:33 +053021170 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21171 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021172 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021173 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021174
Atul Mittal115287b2014-07-08 13:26:33 +053021175 if (0 != status)
21176 {
21177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021178 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021179 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021180 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021181 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021182 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021183 case NL80211_TDLS_DISCOVERY_REQ:
21184 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021186 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021187 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021188 return -ENOTSUPP;
21189 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21191 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021192 return -ENOTSUPP;
21193 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021194
21195 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021196 return 0;
21197}
Chilam NG571c65a2013-01-19 12:27:36 +053021198
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021199static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021200#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21201 const u8 *peer,
21202#else
21203 u8 *peer,
21204#endif
21205 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021206{
21207 int ret;
21208
21209 vos_ssr_protect(__func__);
21210 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21211 vos_ssr_unprotect(__func__);
21212
21213 return ret;
21214}
21215
Chilam NG571c65a2013-01-19 12:27:36 +053021216int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21217 struct net_device *dev, u8 *peer)
21218{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021219 hddLog(VOS_TRACE_LEVEL_INFO,
21220 "tdls send discover req: "MAC_ADDRESS_STR,
21221 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021222#if TDLS_MGMT_VERSION2
21223 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21224 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21225#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021226#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21227 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21228 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21229#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21230 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21231 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21232#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21233 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21234 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21235#else
Chilam NG571c65a2013-01-19 12:27:36 +053021236 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21237 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021238#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021239#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021240}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021241#endif
21242
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021243#ifdef WLAN_FEATURE_GTK_OFFLOAD
21244/*
21245 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21246 * Callback rountine called upon receiving response for
21247 * get offload info
21248 */
21249void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21250 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21251{
21252
21253 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021254 tANI_U8 tempReplayCounter[8];
21255 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021256
21257 ENTER();
21258
21259 if (NULL == pAdapter)
21260 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021262 "%s: HDD adapter is Null", __func__);
21263 return ;
21264 }
21265
21266 if (NULL == pGtkOffloadGetInfoRsp)
21267 {
21268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21269 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21270 return ;
21271 }
21272
21273 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21274 {
21275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21276 "%s: wlan Failed to get replay counter value",
21277 __func__);
21278 return ;
21279 }
21280
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021281 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21282 /* Update replay counter */
21283 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21284 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21285
21286 {
21287 /* changing from little to big endian since supplicant
21288 * works on big endian format
21289 */
21290 int i;
21291 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21292
21293 for (i = 0; i < 8; i++)
21294 {
21295 tempReplayCounter[7-i] = (tANI_U8)p[i];
21296 }
21297 }
21298
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021299 /* Update replay counter to NL */
21300 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021301 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021302}
21303
21304/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021305 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021306 * This function is used to offload GTK rekeying job to the firmware.
21307 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021308int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021309 struct cfg80211_gtk_rekey_data *data)
21310{
21311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21313 hdd_station_ctx_t *pHddStaCtx;
21314 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021315 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021316 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021317 eHalStatus status = eHAL_STATUS_FAILURE;
21318
21319 ENTER();
21320
21321 if (NULL == pAdapter)
21322 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021324 "%s: HDD adapter is Null", __func__);
21325 return -ENODEV;
21326 }
21327
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21329 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21330 pAdapter->sessionId, pAdapter->device_mode));
21331
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021332 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021333 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021334 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021335 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021336 }
21337
21338 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21339 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21340 if (NULL == hHal)
21341 {
21342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21343 "%s: HAL context is Null!!!", __func__);
21344 return -EAGAIN;
21345 }
21346
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021347 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21348 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21349 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21350 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021351 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021352 {
21353 /* changing from big to little endian since driver
21354 * works on little endian format
21355 */
21356 tANI_U8 *p =
21357 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21358 int i;
21359
21360 for (i = 0; i < 8; i++)
21361 {
21362 p[7-i] = data->replay_ctr[i];
21363 }
21364 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021365
21366 if (TRUE == pHddCtx->hdd_wlan_suspended)
21367 {
21368 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021369 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21370 sizeof (tSirGtkOffloadParams));
21371 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021372 pAdapter->sessionId);
21373
21374 if (eHAL_STATUS_SUCCESS != status)
21375 {
21376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21377 "%s: sme_SetGTKOffload failed, returned %d",
21378 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021379
21380 /* Need to clear any trace of key value in the memory.
21381 * Thus zero out the memory even though it is local
21382 * variable.
21383 */
21384 vos_mem_zero(&hddGtkOffloadReqParams,
21385 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021386 return status;
21387 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21389 "%s: sme_SetGTKOffload successfull", __func__);
21390 }
21391 else
21392 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21394 "%s: wlan not suspended GTKOffload request is stored",
21395 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021396 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021397
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021398 /* Need to clear any trace of key value in the memory.
21399 * Thus zero out the memory even though it is local
21400 * variable.
21401 */
21402 vos_mem_zero(&hddGtkOffloadReqParams,
21403 sizeof(hddGtkOffloadReqParams));
21404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021405 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021406 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021407}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021408
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021409int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21410 struct cfg80211_gtk_rekey_data *data)
21411{
21412 int ret;
21413
21414 vos_ssr_protect(__func__);
21415 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21416 vos_ssr_unprotect(__func__);
21417
21418 return ret;
21419}
21420#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021421/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021422 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021423 * This function is used to set access control policy
21424 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021425static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21426 struct net_device *dev,
21427 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021428{
21429 int i;
21430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21431 hdd_hostapd_state_t *pHostapdState;
21432 tsap_Config_t *pConfig;
21433 v_CONTEXT_t pVosContext = NULL;
21434 hdd_context_t *pHddCtx;
21435 int status;
21436
21437 ENTER();
21438
21439 if (NULL == pAdapter)
21440 {
21441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21442 "%s: HDD adapter is Null", __func__);
21443 return -ENODEV;
21444 }
21445
21446 if (NULL == params)
21447 {
21448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21449 "%s: params is Null", __func__);
21450 return -EINVAL;
21451 }
21452
21453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21454 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021455 if (0 != status)
21456 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021457 return status;
21458 }
21459
21460 pVosContext = pHddCtx->pvosContext;
21461 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21462
21463 if (NULL == pHostapdState)
21464 {
21465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21466 "%s: pHostapdState is Null", __func__);
21467 return -EINVAL;
21468 }
21469
21470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21471 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021472 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21473 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21474 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021475
21476 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21477 {
21478 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21479
21480 /* default value */
21481 pConfig->num_accept_mac = 0;
21482 pConfig->num_deny_mac = 0;
21483
21484 /**
21485 * access control policy
21486 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21487 * listed in hostapd.deny file.
21488 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21489 * listed in hostapd.accept file.
21490 */
21491 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21492 {
21493 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21494 }
21495 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21496 {
21497 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21498 }
21499 else
21500 {
21501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21502 "%s:Acl Policy : %d is not supported",
21503 __func__, params->acl_policy);
21504 return -ENOTSUPP;
21505 }
21506
21507 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21508 {
21509 pConfig->num_accept_mac = params->n_acl_entries;
21510 for (i = 0; i < params->n_acl_entries; i++)
21511 {
21512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21513 "** Add ACL MAC entry %i in WhiletList :"
21514 MAC_ADDRESS_STR, i,
21515 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21516
21517 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21518 sizeof(qcmacaddr));
21519 }
21520 }
21521 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21522 {
21523 pConfig->num_deny_mac = params->n_acl_entries;
21524 for (i = 0; i < params->n_acl_entries; i++)
21525 {
21526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21527 "** Add ACL MAC entry %i in BlackList :"
21528 MAC_ADDRESS_STR, i,
21529 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21530
21531 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21532 sizeof(qcmacaddr));
21533 }
21534 }
21535
21536 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21537 {
21538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21539 "%s: SAP Set Mac Acl fail", __func__);
21540 return -EINVAL;
21541 }
21542 }
21543 else
21544 {
21545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021546 "%s: Invalid device_mode = %s (%d)",
21547 __func__, hdd_device_modetoString(pAdapter->device_mode),
21548 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021549 return -EINVAL;
21550 }
21551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021552 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021553 return 0;
21554}
21555
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021556static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21557 struct net_device *dev,
21558 const struct cfg80211_acl_data *params)
21559{
21560 int ret;
21561 vos_ssr_protect(__func__);
21562 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21563 vos_ssr_unprotect(__func__);
21564
21565 return ret;
21566}
21567
Leo Chang9056f462013-08-01 19:21:11 -070021568#ifdef WLAN_NL80211_TESTMODE
21569#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021570void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021571(
21572 void *pAdapter,
21573 void *indCont
21574)
21575{
Leo Changd9df8aa2013-09-26 13:32:26 -070021576 tSirLPHBInd *lphbInd;
21577 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021578 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021579
21580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021581 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021582
c_hpothu73f35e62014-04-18 13:40:08 +053021583 if (pAdapter == NULL)
21584 {
21585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21586 "%s: pAdapter is NULL\n",__func__);
21587 return;
21588 }
21589
Leo Chang9056f462013-08-01 19:21:11 -070021590 if (NULL == indCont)
21591 {
21592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021593 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021594 return;
21595 }
21596
c_hpothu73f35e62014-04-18 13:40:08 +053021597 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021598 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021599 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021600 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021601 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021602 GFP_ATOMIC);
21603 if (!skb)
21604 {
21605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21606 "LPHB timeout, NL buffer alloc fail");
21607 return;
21608 }
21609
Leo Changac3ba772013-10-07 09:47:04 -070021610 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021611 {
21612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21613 "WLAN_HDD_TM_ATTR_CMD put fail");
21614 goto nla_put_failure;
21615 }
Leo Changac3ba772013-10-07 09:47:04 -070021616 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021617 {
21618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21619 "WLAN_HDD_TM_ATTR_TYPE put fail");
21620 goto nla_put_failure;
21621 }
Leo Changac3ba772013-10-07 09:47:04 -070021622 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021623 sizeof(tSirLPHBInd), lphbInd))
21624 {
21625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21626 "WLAN_HDD_TM_ATTR_DATA put fail");
21627 goto nla_put_failure;
21628 }
Leo Chang9056f462013-08-01 19:21:11 -070021629 cfg80211_testmode_event(skb, GFP_ATOMIC);
21630 return;
21631
21632nla_put_failure:
21633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21634 "NLA Put fail");
21635 kfree_skb(skb);
21636
21637 return;
21638}
21639#endif /* FEATURE_WLAN_LPHB */
21640
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021641static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021642{
21643 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21644 int err = 0;
21645#ifdef FEATURE_WLAN_LPHB
21646 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021647 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021648
21649 ENTER();
21650
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021651 err = wlan_hdd_validate_context(pHddCtx);
21652 if (0 != err)
21653 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021654 return err;
21655 }
Leo Chang9056f462013-08-01 19:21:11 -070021656#endif /* FEATURE_WLAN_LPHB */
21657
21658 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21659 if (err)
21660 {
21661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21662 "%s Testmode INV ATTR", __func__);
21663 return err;
21664 }
21665
21666 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21667 {
21668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21669 "%s Testmode INV CMD", __func__);
21670 return -EINVAL;
21671 }
21672
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21674 TRACE_CODE_HDD_CFG80211_TESTMODE,
21675 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021676 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21677 {
21678#ifdef FEATURE_WLAN_LPHB
21679 /* Low Power Heartbeat configuration request */
21680 case WLAN_HDD_TM_CMD_WLAN_HB:
21681 {
21682 int buf_len;
21683 void *buf;
21684 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021685 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021686
21687 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21688 {
21689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21690 "%s Testmode INV DATA", __func__);
21691 return -EINVAL;
21692 }
21693
21694 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21695 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021696
Manjeet Singh3c577442017-02-10 19:03:38 +053021697 if (buf_len > sizeof(*hb_params)) {
21698 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21699 buf_len);
21700 return -ERANGE;
21701 }
21702
Amar Singhal05852702014-02-04 14:40:00 -080021703 hb_params_temp =(tSirLPHBReq *)buf;
21704 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21705 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21706 return -EINVAL;
21707
Leo Chang9056f462013-08-01 19:21:11 -070021708 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21709 if (NULL == hb_params)
21710 {
21711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21712 "%s Request Buffer Alloc Fail", __func__);
21713 return -EINVAL;
21714 }
21715
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021716 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021717 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021718 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21719 hb_params,
21720 wlan_hdd_cfg80211_lphb_ind_handler);
21721 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021722 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21724 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021725 vos_mem_free(hb_params);
21726 }
Leo Chang9056f462013-08-01 19:21:11 -070021727 return 0;
21728 }
21729#endif /* FEATURE_WLAN_LPHB */
21730 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21732 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021733 return -EOPNOTSUPP;
21734 }
21735
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021736 EXIT();
21737 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021738}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021739
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021740static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21742 struct wireless_dev *wdev,
21743#endif
21744 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021745{
21746 int ret;
21747
21748 vos_ssr_protect(__func__);
21749 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21750 vos_ssr_unprotect(__func__);
21751
21752 return ret;
21753}
Leo Chang9056f462013-08-01 19:21:11 -070021754#endif /* CONFIG_NL80211_TESTMODE */
21755
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021756extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021757static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021758 struct net_device *dev,
21759 int idx, struct survey_info *survey)
21760{
21761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21762 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021763 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021764 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021765 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021766 v_S7_t snr,rssi;
21767 int status, i, j, filled = 0;
21768
21769 ENTER();
21770
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021771 if (NULL == pAdapter)
21772 {
21773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21774 "%s: HDD adapter is Null", __func__);
21775 return -ENODEV;
21776 }
21777
21778 if (NULL == wiphy)
21779 {
21780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21781 "%s: wiphy is Null", __func__);
21782 return -ENODEV;
21783 }
21784
21785 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21786 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021787 if (0 != status)
21788 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021789 return status;
21790 }
21791
Mihir Sheted9072e02013-08-21 17:02:29 +053021792 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21793
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021794 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021795 0 != pAdapter->survey_idx ||
21796 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021797 {
21798 /* The survey dump ops when implemented completely is expected to
21799 * return a survey of all channels and the ops is called by the
21800 * kernel with incremental values of the argument 'idx' till it
21801 * returns -ENONET. But we can only support the survey for the
21802 * operating channel for now. survey_idx is used to track
21803 * that the ops is called only once and then return -ENONET for
21804 * the next iteration
21805 */
21806 pAdapter->survey_idx = 0;
21807 return -ENONET;
21808 }
21809
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021810 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21811 {
21812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21813 "%s: Roaming in progress, hence return ", __func__);
21814 return -ENONET;
21815 }
21816
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021817 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21818
21819 wlan_hdd_get_snr(pAdapter, &snr);
21820 wlan_hdd_get_rssi(pAdapter, &rssi);
21821
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021822 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21823 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21824 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021825 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21826 hdd_wlan_get_freq(channel, &freq);
21827
21828
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021829 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021830 {
21831 if (NULL == wiphy->bands[i])
21832 {
21833 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21834 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21835 continue;
21836 }
21837
21838 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21839 {
21840 struct ieee80211_supported_band *band = wiphy->bands[i];
21841
21842 if (band->channels[j].center_freq == (v_U16_t)freq)
21843 {
21844 survey->channel = &band->channels[j];
21845 /* The Rx BDs contain SNR values in dB for the received frames
21846 * while the supplicant expects noise. So we calculate and
21847 * return the value of noise (dBm)
21848 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21849 */
21850 survey->noise = rssi - snr;
21851 survey->filled = SURVEY_INFO_NOISE_DBM;
21852 filled = 1;
21853 }
21854 }
21855 }
21856
21857 if (filled)
21858 pAdapter->survey_idx = 1;
21859 else
21860 {
21861 pAdapter->survey_idx = 0;
21862 return -ENONET;
21863 }
21864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021865 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021866 return 0;
21867}
21868
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021869static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21870 struct net_device *dev,
21871 int idx, struct survey_info *survey)
21872{
21873 int ret;
21874
21875 vos_ssr_protect(__func__);
21876 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21877 vos_ssr_unprotect(__func__);
21878
21879 return ret;
21880}
21881
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021882/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021883 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021884 * this is called when cfg80211 driver resume
21885 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21886 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021887int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021888{
21889 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21890 hdd_adapter_t *pAdapter;
21891 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21892 VOS_STATUS status = VOS_STATUS_SUCCESS;
21893
21894 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021895
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021896 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021897 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021898 return 0;
21899 }
21900
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021901 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21902 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021903
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021904 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021905 {
21906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21907 "%s: Resume SoftAP", __func__);
21908 hdd_set_wlan_suspend_mode(false);
21909 }
21910
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021911 spin_lock(&pHddCtx->schedScan_lock);
21912 pHddCtx->isWiphySuspended = FALSE;
21913 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21914 {
21915 spin_unlock(&pHddCtx->schedScan_lock);
21916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21917 "%s: Return resume is not due to PNO indication", __func__);
21918 return 0;
21919 }
21920 // Reset flag to avoid updatating cfg80211 data old results again
21921 pHddCtx->isSchedScanUpdatePending = FALSE;
21922 spin_unlock(&pHddCtx->schedScan_lock);
21923
21924 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21925
21926 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21927 {
21928 pAdapter = pAdapterNode->pAdapter;
21929 if ( (NULL != pAdapter) &&
21930 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21931 {
21932 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021933 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21935 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021936 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021937 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021938 {
21939 /* Acquire wakelock to handle the case where APP's tries to
21940 * suspend immediately after updating the scan results. Whis
21941 * results in app's is in suspended state and not able to
21942 * process the connect request to AP
21943 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021944 hdd_prevent_suspend_timeout(2000,
21945 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021946 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021947 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021948
21949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21950 "%s : cfg80211 scan result database updated", __func__);
21951
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021952 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021953 return 0;
21954
21955 }
21956 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21957 pAdapterNode = pNext;
21958 }
21959
21960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21961 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021962 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021963 return 0;
21964}
21965
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021966int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21967{
21968 int ret;
21969
21970 vos_ssr_protect(__func__);
21971 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21972 vos_ssr_unprotect(__func__);
21973
21974 return ret;
21975}
21976
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021977/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021978 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021979 * this is called when cfg80211 driver suspends
21980 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021981int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021982 struct cfg80211_wowlan *wow)
21983{
21984 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021985 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021986
21987 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021988
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021989 ret = wlan_hdd_validate_context(pHddCtx);
21990 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021991 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021992 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021993 }
21994
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021995 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21997 "%s: Suspend SoftAP", __func__);
21998 hdd_set_wlan_suspend_mode(true);
21999 }
22000
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022001
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022002 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22003 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22004 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022005 pHddCtx->isWiphySuspended = TRUE;
22006
22007 EXIT();
22008
22009 return 0;
22010}
22011
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022012int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22013 struct cfg80211_wowlan *wow)
22014{
22015 int ret;
22016
22017 vos_ssr_protect(__func__);
22018 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22019 vos_ssr_unprotect(__func__);
22020
22021 return ret;
22022}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022023
22024#ifdef FEATURE_OEM_DATA_SUPPORT
22025static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022026 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022027{
22028 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22029
22030 ENTER();
22031
22032 if (wlan_hdd_validate_context(pHddCtx)) {
22033 return;
22034 }
22035 if (!pMsg)
22036 {
22037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22038 return;
22039 }
22040
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022041 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022042
22043 EXIT();
22044 return;
22045
22046}
22047
22048void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022049 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022050{
22051 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22052
22053 ENTER();
22054
22055 if (wlan_hdd_validate_context(pHddCtx)) {
22056 return;
22057 }
22058
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022059 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022060
22061 switch(evType) {
22062 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022063 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022064 break;
22065 default:
22066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22067 break;
22068 }
22069 EXIT();
22070}
22071#endif
22072
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22074 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022075/**
22076 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22077 * @wiphy: Pointer to wiphy
22078 * @wdev: Pointer to wireless device structure
22079 *
22080 * This function is used to abort an ongoing scan
22081 *
22082 * Return: None
22083 */
22084static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22085 struct wireless_dev *wdev)
22086{
22087 struct net_device *dev = wdev->netdev;
22088 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22089 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22090 int ret;
22091
22092 ENTER();
22093
22094 if (NULL == adapter) {
22095 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22096 return;
22097 }
22098
22099 ret = wlan_hdd_validate_context(hdd_ctx);
22100 if (0 != ret)
22101 return;
22102
22103 wlan_hdd_scan_abort(adapter);
22104
22105 return;
22106}
22107
22108/**
22109 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22110 * @wiphy: Pointer to wiphy
22111 * @wdev: Pointer to wireless device structure
22112 *
22113 * Return: None
22114 */
22115void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22116 struct wireless_dev *wdev)
22117{
22118 vos_ssr_protect(__func__);
22119 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22120 vos_ssr_unprotect(__func__);
22121
22122 return;
22123}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022124#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022125
Abhishek Singh936c6932017-11-07 17:28:23 +053022126#ifdef CHANNEL_SWITCH_SUPPORTED
22127/**
22128 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22129 * channel in SAP/GO
22130 * @wiphy: wiphy pointer
22131 * @dev: dev pointer.
22132 * @csa_params: Change channel params
22133 *
22134 * This function is called to switch channel in SAP/GO
22135 *
22136 * Return: 0 if success else return non zero
22137 */
22138static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22139 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22140{
22141 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22142 hdd_context_t *hdd_ctx;
22143 uint8_t channel;
22144 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022145 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022146 v_CONTEXT_t vos_ctx;
22147
22148 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22149
22150 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22151 ret = wlan_hdd_validate_context(hdd_ctx);
22152 if (ret)
22153 return ret;
22154
22155 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22156 if (!vos_ctx) {
22157 hddLog(LOGE, FL("Vos ctx is null"));
22158 return -EINVAL;
22159 }
22160
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022161 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022162 return -ENOTSUPP;
22163
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022164 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22165 if (!sap_ctx) {
22166 hddLog(LOGE, FL("sap_ctx is NULL"));
22167 return -EINVAL;
22168 }
22169
22170 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22171 if (ret)
22172 return ret;
22173
22174 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22175
Abhishek Singh936c6932017-11-07 17:28:23 +053022176 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022177 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022178
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022179 if (ret) {
22180 wlansap_reset_chan_change_in_progress(sap_ctx);
22181 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22182 }
22183
Abhishek Singh936c6932017-11-07 17:28:23 +053022184 return ret;
22185}
22186
22187/**
22188 * wlan_hdd_cfg80211_channel_switch()- function to switch
22189 * channel in SAP/GO
22190 * @wiphy: wiphy pointer
22191 * @dev: dev pointer.
22192 * @csa_params: Change channel params
22193 *
22194 * This function is called to switch channel in SAP/GO
22195 *
22196 * Return: 0 if success else return non zero
22197 */
22198static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22199 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22200{
22201 int ret;
22202
22203 vos_ssr_protect(__func__);
22204 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22205 vos_ssr_unprotect(__func__);
22206
22207 return ret;
22208}
22209#endif
22210
Jeff Johnson295189b2012-06-20 16:38:30 -070022211/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022212static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022213{
22214 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22215 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22216 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22217 .change_station = wlan_hdd_change_station,
22218#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22219 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22220 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22221 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022222#else
22223 .start_ap = wlan_hdd_cfg80211_start_ap,
22224 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22225 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022226#endif
22227 .change_bss = wlan_hdd_cfg80211_change_bss,
22228 .add_key = wlan_hdd_cfg80211_add_key,
22229 .get_key = wlan_hdd_cfg80211_get_key,
22230 .del_key = wlan_hdd_cfg80211_del_key,
22231 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022232#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022233 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022234#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022235 .scan = wlan_hdd_cfg80211_scan,
22236 .connect = wlan_hdd_cfg80211_connect,
22237 .disconnect = wlan_hdd_cfg80211_disconnect,
22238 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22239 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22240 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22241 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22242 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022243 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22244 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022245 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022246#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22247 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22248 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22249 .set_txq_params = wlan_hdd_set_txq_params,
22250#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022251 .get_station = wlan_hdd_cfg80211_get_station,
22252 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22253 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022254 .add_station = wlan_hdd_cfg80211_add_station,
22255#ifdef FEATURE_WLAN_LFR
22256 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22257 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22258 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22259#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022260#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22261 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22262#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022263#ifdef FEATURE_WLAN_TDLS
22264 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22265 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22266#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022267#ifdef WLAN_FEATURE_GTK_OFFLOAD
22268 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22269#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022270#ifdef FEATURE_WLAN_SCAN_PNO
22271 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22272 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22273#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022274 .resume = wlan_hdd_cfg80211_resume_wlan,
22275 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022276 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022277#ifdef WLAN_NL80211_TESTMODE
22278 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22279#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022280 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022281#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22282 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022283 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022284#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022285#ifdef CHANNEL_SWITCH_SUPPORTED
22286 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22287#endif
22288
Jeff Johnson295189b2012-06-20 16:38:30 -070022289};
22290