blob: 62ac453438744c3b727f6d9d0275a518066e1440 [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
Dundi Raviteja18d0c062018-11-13 19:56:45 +05305084 if (j != pReqMsg->buckets[bktIndex].numChannels) {
5085 hddLog(LOG1, FL("Input parameters didn't match"));
5086 return -EINVAL;
5087 }
5088
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305089 bktIndex++;
5090 }
5091
5092 return 0;
5093}
5094
5095
5096/*
5097 * define short names for the global vendor params
5098 * used by wlan_hdd_cfg80211_extscan_start()
5099 */
5100#define PARAM_MAX \
5101QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5102#define PARAM_REQUEST_ID \
5103QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5104#define PARAM_BASE_PERIOD \
5105QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5106#define PARAM_MAX_AP_PER_SCAN \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5108#define PARAM_RPT_THRHLD_PERCENT \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5110#define PARAM_RPT_THRHLD_NUM_SCANS \
5111QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5112#define PARAM_NUM_BUCKETS \
5113QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5114
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305115static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305116 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305117 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305118{
Dino Myclee8843b32014-07-04 14:21:45 +05305119 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305120 struct net_device *dev = wdev->netdev;
5121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5122 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5123 struct nlattr *tb[PARAM_MAX + 1];
5124 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305126 tANI_U32 request_id;
5127 struct hdd_ext_scan_context *context;
5128 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305129
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305130 ENTER();
5131
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305132 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305133 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305134
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305135 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136 data, dataLen,
5137 wlan_hdd_extscan_config_policy)) {
5138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5139 return -EINVAL;
5140 }
5141
5142 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305143 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5145 return -EINVAL;
5146 }
5147
Dino Myclee8843b32014-07-04 14:21:45 +05305148 pReqMsg = (tpSirEXTScanStartReqParams)
5149 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305150 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5152 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305153 }
5154
5155 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305156 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5158
5159 pReqMsg->sessionId = pAdapter->sessionId;
5160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5161
5162 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305163 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5165 goto fail;
5166 }
5167 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305168 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5170 pReqMsg->basePeriod);
5171
5172 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305173 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5175 goto fail;
5176 }
5177 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5180 pReqMsg->maxAPperScan);
5181
5182 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305183 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5185 goto fail;
5186 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305187 pReqMsg->reportThresholdPercent = nla_get_u8(
5188 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305189 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305190 pReqMsg->reportThresholdPercent);
5191
5192 /* Parse and fetch report threshold num scans */
5193 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5194 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5195 goto fail;
5196 }
5197 pReqMsg->reportThresholdNumScans = nla_get_u8(
5198 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5199 hddLog(LOG1, FL("Report Threshold num scans %d"),
5200 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305201
5202 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5205 goto fail;
5206 }
5207 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305208 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305209 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5210 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5211 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5212 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5213 }
5214 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5215 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305216
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5219 goto fail;
5220 }
5221
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305222 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305223
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305224 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5225 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305226
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305227 context = &pHddCtx->ext_scan_context;
5228 spin_lock(&hdd_context_lock);
5229 INIT_COMPLETION(context->response_event);
5230 context->request_id = request_id = pReqMsg->requestId;
5231 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305232
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5234 if (!HAL_STATUS_SUCCESS(status)) {
5235 hddLog(VOS_TRACE_LEVEL_ERROR,
5236 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 goto fail;
5238 }
5239
Srinivas Dasari91727c12016-03-23 17:59:06 +05305240 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5241
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305242 /* request was sent -- wait for the response */
5243 rc = wait_for_completion_timeout(&context->response_event,
5244 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5245
5246 if (!rc) {
5247 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5248 retval = -ETIMEDOUT;
5249 } else {
5250 spin_lock(&hdd_context_lock);
5251 if (context->request_id == request_id)
5252 retval = context->response_status;
5253 else
5254 retval = -EINVAL;
5255 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256 }
5257
Dino Myclee8843b32014-07-04 14:21:45 +05305258 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305260 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305261
5262fail:
5263 vos_mem_free(pReqMsg);
5264 return -EINVAL;
5265}
5266
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305267/*
5268 * done with short names for the global vendor params
5269 * used by wlan_hdd_cfg80211_extscan_start()
5270 */
5271#undef PARAM_MAX
5272#undef PARAM_REQUEST_ID
5273#undef PARAM_BASE_PERIOD
5274#undef PARAMS_MAX_AP_PER_SCAN
5275#undef PARAMS_RPT_THRHLD_PERCENT
5276#undef PARAMS_RPT_THRHLD_NUM_SCANS
5277#undef PARAMS_NUM_BUCKETS
5278
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305279static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5280 struct wireless_dev *wdev,
5281 const void *data, int dataLen)
5282{
5283 int ret = 0;
5284
5285 vos_ssr_protect(__func__);
5286 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5287 vos_ssr_unprotect(__func__);
5288
5289 return ret;
5290}
5291
5292static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305293 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305294 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305295{
Dino Myclee8843b32014-07-04 14:21:45 +05305296 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305297 struct net_device *dev = wdev->netdev;
5298 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5299 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5300 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5301 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305302 int retval;
5303 unsigned long rc;
5304 struct hdd_ext_scan_context *context;
5305 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305307 ENTER();
5308
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305309 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305310 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305311
Dino Mycle6fb96c12014-06-10 11:52:40 +05305312 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5313 data, dataLen,
5314 wlan_hdd_extscan_config_policy)) {
5315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5316 return -EINVAL;
5317 }
5318
5319 /* Parse and fetch request Id */
5320 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5322 return -EINVAL;
5323 }
5324
Dino Myclee8843b32014-07-04 14:21:45 +05305325 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305326 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305327 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305328
Dino Myclee8843b32014-07-04 14:21:45 +05305329 reqMsg.sessionId = pAdapter->sessionId;
5330 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305331
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305332 context = &pHddCtx->ext_scan_context;
5333 spin_lock(&hdd_context_lock);
5334 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305335 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305336 spin_unlock(&hdd_context_lock);
5337
Dino Myclee8843b32014-07-04 14:21:45 +05305338 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305339 if (!HAL_STATUS_SUCCESS(status)) {
5340 hddLog(VOS_TRACE_LEVEL_ERROR,
5341 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 return -EINVAL;
5343 }
5344
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305345 /* request was sent -- wait for the response */
5346 rc = wait_for_completion_timeout(&context->response_event,
5347 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5348
5349 if (!rc) {
5350 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5351 retval = -ETIMEDOUT;
5352 } else {
5353 spin_lock(&hdd_context_lock);
5354 if (context->request_id == request_id)
5355 retval = context->response_status;
5356 else
5357 retval = -EINVAL;
5358 spin_unlock(&hdd_context_lock);
5359 }
5360
5361 return retval;
5362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305363 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305364 return 0;
5365}
5366
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305367static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5368 struct wireless_dev *wdev,
5369 const void *data, int dataLen)
5370{
5371 int ret = 0;
5372
5373 vos_ssr_protect(__func__);
5374 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5375 vos_ssr_unprotect(__func__);
5376
5377 return ret;
5378}
5379
5380static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305381 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305382 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305383{
Dino Myclee8843b32014-07-04 14:21:45 +05305384 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305385 struct net_device *dev = wdev->netdev;
5386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5387 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5388 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5389 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305390 struct hdd_ext_scan_context *context;
5391 tANI_U32 request_id;
5392 unsigned long rc;
5393 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 ENTER();
5396
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305397 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305398 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305399
Dino Mycle6fb96c12014-06-10 11:52:40 +05305400 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5401 data, dataLen,
5402 wlan_hdd_extscan_config_policy)) {
5403 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5404 return -EINVAL;
5405 }
5406
5407 /* Parse and fetch request Id */
5408 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5410 return -EINVAL;
5411 }
5412
Dino Myclee8843b32014-07-04 14:21:45 +05305413 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305414 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305415 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305416
Dino Myclee8843b32014-07-04 14:21:45 +05305417 reqMsg.sessionId = pAdapter->sessionId;
5418 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305419
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305420 context = &pHddCtx->ext_scan_context;
5421 spin_lock(&hdd_context_lock);
5422 INIT_COMPLETION(context->response_event);
5423 context->request_id = request_id = reqMsg.requestId;
5424 spin_unlock(&hdd_context_lock);
5425
Dino Myclee8843b32014-07-04 14:21:45 +05305426 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305427 if (!HAL_STATUS_SUCCESS(status)) {
5428 hddLog(VOS_TRACE_LEVEL_ERROR,
5429 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305430 return -EINVAL;
5431 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305432
5433 /* request was sent -- wait for the response */
5434 rc = wait_for_completion_timeout(&context->response_event,
5435 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5436 if (!rc) {
5437 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5438 retval = -ETIMEDOUT;
5439 } else {
5440 spin_lock(&hdd_context_lock);
5441 if (context->request_id == request_id)
5442 retval = context->response_status;
5443 else
5444 retval = -EINVAL;
5445 spin_unlock(&hdd_context_lock);
5446 }
5447
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305448 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305449 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305450}
5451
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305452static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5453 struct wireless_dev *wdev,
5454 const void *data, int dataLen)
5455{
5456 int ret = 0;
5457
5458 vos_ssr_protect(__func__);
5459 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5460 vos_ssr_unprotect(__func__);
5461
5462 return ret;
5463}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464#endif /* WLAN_FEATURE_EXTSCAN */
5465
Atul Mittal115287b2014-07-08 13:26:33 +05305466/*EXT TDLS*/
5467static const struct nla_policy
5468wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5469{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305470 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5471 .type = NLA_UNSPEC,
5472 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305473 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5474 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5475 {.type = NLA_S32 },
5476 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5477 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5478
5479};
5480
5481static const struct nla_policy
5482wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5483{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305484 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5485 .type = NLA_UNSPEC,
5486 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305487
5488};
5489
5490static const struct nla_policy
5491wlan_hdd_tdls_config_state_change_policy[
5492 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5493{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305494 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5495 .type = NLA_UNSPEC,
5496 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305497 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5498 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305499 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5500 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5501 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305502
5503};
5504
5505static const struct nla_policy
5506wlan_hdd_tdls_config_get_status_policy[
5507 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5508{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305509 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5510 .type = NLA_UNSPEC,
5511 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305512 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5513 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305514 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5515 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5516 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305517
5518};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305519
5520static const struct nla_policy
5521wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5522{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305523 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5524 .type = NLA_UNSPEC,
5525 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305526};
5527
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305528static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305529 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305530 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305531 int data_len)
5532{
5533
5534 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5535 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305537 ENTER();
5538
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305539 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305540 return -EINVAL;
5541 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305542 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305543 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305544 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305545 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305546 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305547 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305548 return -ENOTSUPP;
5549 }
5550
5551 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5552 data, data_len, wlan_hdd_mac_config)) {
5553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5554 return -EINVAL;
5555 }
5556
5557 /* Parse and fetch mac address */
5558 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5560 return -EINVAL;
5561 }
5562
5563 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5564 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5565 VOS_MAC_ADDR_LAST_3_BYTES);
5566
Siddharth Bhal76972212014-10-15 16:22:51 +05305567 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5568
5569 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305570 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5571 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305572 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5573 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5574 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5575 {
5576 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5577 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5578 VOS_MAC_ADDRESS_LEN);
5579 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305580 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305581
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305582 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5583 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305585 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305586 return 0;
5587}
5588
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305589static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5590 struct wireless_dev *wdev,
5591 const void *data,
5592 int data_len)
5593{
5594 int ret = 0;
5595
5596 vos_ssr_protect(__func__);
5597 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5598 vos_ssr_unprotect(__func__);
5599
5600 return ret;
5601}
5602
5603static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305604 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305605 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305606 int data_len)
5607{
5608 u8 peer[6] = {0};
5609 struct net_device *dev = wdev->netdev;
5610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5611 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5612 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5613 eHalStatus ret;
5614 tANI_S32 state;
5615 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305616 tANI_S32 global_operating_class = 0;
5617 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305618 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305619 int retVal;
5620
5621 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305622
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305623 if (!pAdapter) {
5624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5625 return -EINVAL;
5626 }
5627
Atul Mittal115287b2014-07-08 13:26:33 +05305628 ret = wlan_hdd_validate_context(pHddCtx);
5629 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305631 return -EINVAL;
5632 }
5633 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305635 return -ENOTSUPP;
5636 }
5637 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5638 data, data_len,
5639 wlan_hdd_tdls_config_get_status_policy)) {
5640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5641 return -EINVAL;
5642 }
5643
5644 /* Parse and fetch mac address */
5645 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5647 return -EINVAL;
5648 }
5649
5650 memcpy(peer, nla_data(
5651 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5652 sizeof(peer));
5653 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5654
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305655 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305656
Atul Mittal115287b2014-07-08 13:26:33 +05305657 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305658 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305659 NLMSG_HDRLEN);
5660
5661 if (!skb) {
5662 hddLog(VOS_TRACE_LEVEL_ERROR,
5663 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5664 return -EINVAL;
5665 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305666 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 +05305667 reason,
5668 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305669 global_operating_class,
5670 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305671 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305672 if (nla_put_s32(skb,
5673 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5674 state) ||
5675 nla_put_s32(skb,
5676 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5677 reason) ||
5678 nla_put_s32(skb,
5679 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5680 global_operating_class) ||
5681 nla_put_s32(skb,
5682 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5683 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305684
5685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5686 goto nla_put_failure;
5687 }
5688
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305689 retVal = cfg80211_vendor_cmd_reply(skb);
5690 EXIT();
5691 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305692
5693nla_put_failure:
5694 kfree_skb(skb);
5695 return -EINVAL;
5696}
5697
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305698static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5699 struct wireless_dev *wdev,
5700 const void *data,
5701 int data_len)
5702{
5703 int ret = 0;
5704
5705 vos_ssr_protect(__func__);
5706 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5707 vos_ssr_unprotect(__func__);
5708
5709 return ret;
5710}
5711
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305712static int wlan_hdd_cfg80211_exttdls_callback(
5713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5714 const tANI_U8* mac,
5715#else
5716 tANI_U8* mac,
5717#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305718 tANI_S32 state,
5719 tANI_S32 reason,
5720 void *ctx)
5721{
5722 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305723 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305724 tANI_S32 global_operating_class = 0;
5725 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305726 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305727
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305728 ENTER();
5729
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305730 if (!pAdapter) {
5731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5732 return -EINVAL;
5733 }
5734
5735 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305736 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305738 return -EINVAL;
5739 }
5740
5741 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305743 return -ENOTSUPP;
5744 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305745 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5747 NULL,
5748#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305749 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5750 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5751 GFP_KERNEL);
5752
5753 if (!skb) {
5754 hddLog(VOS_TRACE_LEVEL_ERROR,
5755 FL("cfg80211_vendor_event_alloc failed"));
5756 return -EINVAL;
5757 }
5758 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305759 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5760 reason,
5761 state,
5762 global_operating_class,
5763 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305764 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5765 MAC_ADDR_ARRAY(mac));
5766
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305767 if (nla_put(skb,
5768 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5769 VOS_MAC_ADDR_SIZE, mac) ||
5770 nla_put_s32(skb,
5771 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5772 state) ||
5773 nla_put_s32(skb,
5774 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5775 reason) ||
5776 nla_put_s32(skb,
5777 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5778 channel) ||
5779 nla_put_s32(skb,
5780 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5781 global_operating_class)
5782 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5784 goto nla_put_failure;
5785 }
5786
5787 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305788 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305789 return (0);
5790
5791nla_put_failure:
5792 kfree_skb(skb);
5793 return -EINVAL;
5794}
5795
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305796static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305797 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305798 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305799 int data_len)
5800{
5801 u8 peer[6] = {0};
5802 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305803 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5804 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5805 eHalStatus status;
5806 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305807 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305808 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305809
5810 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305811
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305812 if (!dev) {
5813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5814 return -EINVAL;
5815 }
5816
5817 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5818 if (!pAdapter) {
5819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5820 return -EINVAL;
5821 }
5822
Atul Mittal115287b2014-07-08 13:26:33 +05305823 status = wlan_hdd_validate_context(pHddCtx);
5824 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305826 return -EINVAL;
5827 }
5828 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305830 return -ENOTSUPP;
5831 }
5832 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5833 data, data_len,
5834 wlan_hdd_tdls_config_enable_policy)) {
5835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5836 return -EINVAL;
5837 }
5838
5839 /* Parse and fetch mac address */
5840 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5842 return -EINVAL;
5843 }
5844
5845 memcpy(peer, nla_data(
5846 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5847 sizeof(peer));
5848 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5849
5850 /* Parse and fetch channel */
5851 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5853 return -EINVAL;
5854 }
5855 pReqMsg.channel = nla_get_s32(
5856 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5858
5859 /* Parse and fetch global operating class */
5860 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5862 return -EINVAL;
5863 }
5864 pReqMsg.global_operating_class = nla_get_s32(
5865 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5866 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5867 pReqMsg.global_operating_class);
5868
5869 /* Parse and fetch latency ms */
5870 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5872 return -EINVAL;
5873 }
5874 pReqMsg.max_latency_ms = nla_get_s32(
5875 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5876 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5877 pReqMsg.max_latency_ms);
5878
5879 /* Parse and fetch required bandwidth kbps */
5880 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5882 return -EINVAL;
5883 }
5884
5885 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5886 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5888 pReqMsg.min_bandwidth_kbps);
5889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305890 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305891 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305892 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305893 wlan_hdd_cfg80211_exttdls_callback);
5894
5895 EXIT();
5896 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305897}
5898
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305899static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5900 struct wireless_dev *wdev,
5901 const void *data,
5902 int data_len)
5903{
5904 int ret = 0;
5905
5906 vos_ssr_protect(__func__);
5907 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5908 vos_ssr_unprotect(__func__);
5909
5910 return ret;
5911}
5912
5913static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305914 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305915 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305916 int data_len)
5917{
5918 u8 peer[6] = {0};
5919 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305920 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5921 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5922 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305923 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305924 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305925
5926 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305927
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305928 if (!dev) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5930 return -EINVAL;
5931 }
5932
5933 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5934 if (!pAdapter) {
5935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5936 return -EINVAL;
5937 }
5938
Atul Mittal115287b2014-07-08 13:26:33 +05305939 status = wlan_hdd_validate_context(pHddCtx);
5940 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305941 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305942 return -EINVAL;
5943 }
5944 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305945 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305946 return -ENOTSUPP;
5947 }
5948 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5949 data, data_len,
5950 wlan_hdd_tdls_config_disable_policy)) {
5951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5952 return -EINVAL;
5953 }
5954 /* Parse and fetch mac address */
5955 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5956 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5957 return -EINVAL;
5958 }
5959
5960 memcpy(peer, nla_data(
5961 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5962 sizeof(peer));
5963 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305965 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5966
5967 EXIT();
5968 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305969}
5970
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305971static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5972 struct wireless_dev *wdev,
5973 const void *data,
5974 int data_len)
5975{
5976 int ret = 0;
5977
5978 vos_ssr_protect(__func__);
5979 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5980 vos_ssr_unprotect(__func__);
5981
5982 return ret;
5983}
5984
Dasari Srinivas7875a302014-09-26 17:50:57 +05305985static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305986__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305987 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305988 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305989{
5990 struct net_device *dev = wdev->netdev;
5991 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5992 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5993 struct sk_buff *skb = NULL;
5994 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305995 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305997 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305998
5999 ret = wlan_hdd_validate_context(pHddCtx);
6000 if (0 != ret)
6001 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306002 return ret;
6003 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306004 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6005 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6006 fset |= WIFI_FEATURE_INFRA;
6007 }
6008
6009 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6010 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6011 fset |= WIFI_FEATURE_INFRA_5G;
6012 }
6013
6014#ifdef WLAN_FEATURE_P2P
6015 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6016 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6017 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6018 fset |= WIFI_FEATURE_P2P;
6019 }
6020#endif
6021
6022 /* Soft-AP is supported currently by default */
6023 fset |= WIFI_FEATURE_SOFT_AP;
6024
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306025 /* HOTSPOT is a supplicant feature, enable it by default */
6026 fset |= WIFI_FEATURE_HOTSPOT;
6027
Dasari Srinivas7875a302014-09-26 17:50:57 +05306028#ifdef WLAN_FEATURE_EXTSCAN
6029 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306030 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6031 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6032 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033 fset |= WIFI_FEATURE_EXTSCAN;
6034 }
6035#endif
6036
Dasari Srinivas7875a302014-09-26 17:50:57 +05306037 if (sme_IsFeatureSupportedByFW(NAN)) {
6038 hddLog(LOG1, FL("NAN is supported by firmware"));
6039 fset |= WIFI_FEATURE_NAN;
6040 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306041
6042 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306043 if (sme_IsFeatureSupportedByFW(RTT) &&
6044 pHddCtx->cfg_ini->enable_rtt_support) {
6045 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046 fset |= WIFI_FEATURE_D2AP_RTT;
6047 }
6048
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306049 if (sme_IsFeatureSupportedByFW(RTT3)) {
6050 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6051 fset |= WIFI_FEATURE_RTT3;
6052 }
6053
Dasari Srinivas7875a302014-09-26 17:50:57 +05306054#ifdef FEATURE_WLAN_BATCH_SCAN
6055 if (fset & WIFI_FEATURE_EXTSCAN) {
6056 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6057 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6058 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6059 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6060 fset |= WIFI_FEATURE_BATCH_SCAN;
6061 }
6062#endif
6063
6064#ifdef FEATURE_WLAN_SCAN_PNO
6065 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6066 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6067 hddLog(LOG1, FL("PNO is supported by firmware"));
6068 fset |= WIFI_FEATURE_PNO;
6069 }
6070#endif
6071
6072 /* STA+STA is supported currently by default */
6073 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6074
6075#ifdef FEATURE_WLAN_TDLS
6076 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6077 sme_IsFeatureSupportedByFW(TDLS)) {
6078 hddLog(LOG1, FL("TDLS is supported by firmware"));
6079 fset |= WIFI_FEATURE_TDLS;
6080 }
6081
6082 /* TDLS_OFFCHANNEL is not supported currently by default */
6083#endif
6084
6085#ifdef WLAN_AP_STA_CONCURRENCY
6086 /* AP+STA concurrency is supported currently by default */
6087 fset |= WIFI_FEATURE_AP_STA;
6088#endif
6089
Mukul Sharma5add0532015-08-17 15:57:47 +05306090#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306091 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6092 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306093 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6094 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306095 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306096#endif
6097
Dasari Srinivas7875a302014-09-26 17:50:57 +05306098 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6099 NLMSG_HDRLEN);
6100
6101 if (!skb) {
6102 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6103 return -EINVAL;
6104 }
6105 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6106
6107 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6108 hddLog(LOGE, FL("nla put fail"));
6109 goto nla_put_failure;
6110 }
6111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306112 ret = cfg80211_vendor_cmd_reply(skb);
6113 EXIT();
6114 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306115
6116nla_put_failure:
6117 kfree_skb(skb);
6118 return -EINVAL;
6119}
6120
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306121static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306122wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6123 struct wireless_dev *wdev,
6124 const void *data, int data_len)
6125{
6126 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306127 vos_ssr_protect(__func__);
6128 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6129 vos_ssr_unprotect(__func__);
6130
6131 return ret;
6132}
6133
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306134
6135static const struct
6136nla_policy
6137qca_wlan_vendor_wifi_logger_get_ring_data_policy
6138[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6139 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6140 = {.type = NLA_U32 },
6141};
6142
6143static int
6144 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6145 struct wireless_dev *wdev,
6146 const void *data,
6147 int data_len)
6148{
6149 int ret;
6150 VOS_STATUS status;
6151 uint32_t ring_id;
6152 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6153 struct nlattr *tb
6154 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6155
6156 ENTER();
6157
6158 ret = wlan_hdd_validate_context(hdd_ctx);
6159 if (0 != ret) {
6160 return ret;
6161 }
6162
6163 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6164 data, data_len,
6165 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6166 hddLog(LOGE, FL("Invalid attribute"));
6167 return -EINVAL;
6168 }
6169
6170 /* Parse and fetch ring id */
6171 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6172 hddLog(LOGE, FL("attr ATTR failed"));
6173 return -EINVAL;
6174 }
6175
6176 ring_id = nla_get_u32(
6177 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6178
6179 hddLog(LOG1, FL("Bug report triggered by framework"));
6180
6181 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6182 WLAN_LOG_INDICATOR_FRAMEWORK,
6183 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306184 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306185 );
6186 if (VOS_STATUS_SUCCESS != status) {
6187 hddLog(LOGE, FL("Failed to trigger bug report"));
6188
6189 return -EINVAL;
6190 }
6191
6192 return 0;
6193
6194
6195}
6196
6197
6198static int
6199 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6200 struct wireless_dev *wdev,
6201 const void *data,
6202 int data_len)
6203{
6204 int ret = 0;
6205
6206 vos_ssr_protect(__func__);
6207 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6208 wdev, data, data_len);
6209 vos_ssr_unprotect(__func__);
6210
6211 return ret;
6212
6213}
6214
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306215#define MAX_CONCURRENT_MATRIX \
6216 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6217#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6218 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6219static const struct nla_policy
6220wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6221 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6222};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306223
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306224static int
6225__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306226 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306227 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306228{
6229 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6230 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306231 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306232 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306233 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6234 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306235
6236 ENTER();
6237
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306238 ret = wlan_hdd_validate_context(pHddCtx);
6239 if (0 != ret)
6240 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306241 return ret;
6242 }
6243
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306244 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6245 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306246 hddLog(LOGE, FL("Invalid ATTR"));
6247 return -EINVAL;
6248 }
6249
6250 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306251 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306252 hddLog(LOGE, FL("Attr max feature set size failed"));
6253 return -EINVAL;
6254 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306255 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306256 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6257
6258 /* Fill feature combination matrix */
6259 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306260 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6261 WIFI_FEATURE_P2P;
6262
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306263 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6264 WIFI_FEATURE_SOFT_AP;
6265
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306266 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6267 WIFI_FEATURE_SOFT_AP;
6268
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306269 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6270 WIFI_FEATURE_SOFT_AP |
6271 WIFI_FEATURE_P2P;
6272
6273 /* Add more feature combinations here */
6274
6275 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6276 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6277 hddLog(LOG1, "Feature set matrix");
6278 for (i = 0; i < feature_sets; i++)
6279 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6280
6281 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6282 sizeof(u32) * feature_sets +
6283 NLMSG_HDRLEN);
6284
6285 if (reply_skb) {
6286 if (nla_put_u32(reply_skb,
6287 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6288 feature_sets) ||
6289 nla_put(reply_skb,
6290 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6291 sizeof(u32) * feature_sets, feature_set_matrix)) {
6292 hddLog(LOGE, FL("nla put fail"));
6293 kfree_skb(reply_skb);
6294 return -EINVAL;
6295 }
6296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306297 ret = cfg80211_vendor_cmd_reply(reply_skb);
6298 EXIT();
6299 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 }
6301 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6302 return -ENOMEM;
6303
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304}
6305
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306306#undef MAX_CONCURRENT_MATRIX
6307#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6308
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306309static int
6310wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6311 struct wireless_dev *wdev,
6312 const void *data, int data_len)
6313{
6314 int ret = 0;
6315
6316 vos_ssr_protect(__func__);
6317 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6318 data_len);
6319 vos_ssr_unprotect(__func__);
6320
6321 return ret;
6322}
6323
c_manjeecfd1efb2015-09-25 19:32:34 +05306324
6325static int
6326__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6327 struct wireless_dev *wdev,
6328 const void *data, int data_len)
6329{
6330 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6331 int ret;
6332 ENTER();
6333
6334 ret = wlan_hdd_validate_context(pHddCtx);
6335 if (0 != ret)
6336 {
6337 return ret;
6338 }
6339
6340 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6341 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6342 {
6343 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306344 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306345 }
6346 /*call common API for FW mem dump req*/
6347 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6348
Abhishek Singhc783fa72015-12-09 18:07:34 +05306349 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306350 {
6351 /*indicate to userspace the status of fw mem dump */
6352 wlan_indicate_mem_dump_complete(true);
6353 }
6354 else
6355 {
6356 /*else send failure to userspace */
6357 wlan_indicate_mem_dump_complete(false);
6358 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306359 EXIT();
6360 return ret;
6361}
6362
6363/**
6364 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6365 * @wiphy: pointer to wireless wiphy structure.
6366 * @wdev: pointer to wireless_dev structure.
6367 * @data: Pointer to the NL data.
6368 * @data_len:Length of @data
6369 *
6370 * This is called when wlan driver needs to get the firmware memory dump
6371 * via vendor specific command.
6372 *
6373 * Return: 0 on success, error number otherwise.
6374 */
6375
6376static int
6377wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6378 struct wireless_dev *wdev,
6379 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306380{
6381 int ret = 0;
6382 vos_ssr_protect(__func__);
6383 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6384 data_len);
6385 vos_ssr_unprotect(__func__);
6386 return ret;
6387}
c_manjeecfd1efb2015-09-25 19:32:34 +05306388
Sushant Kaushik8e644982015-09-23 12:18:54 +05306389static const struct
6390nla_policy
6391qca_wlan_vendor_wifi_logger_start_policy
6392[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6393 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6394 = {.type = NLA_U32 },
6395 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6396 = {.type = NLA_U32 },
6397 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6398 = {.type = NLA_U32 },
6399};
6400
6401/**
6402 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6403 * or disable the collection of packet statistics from the firmware
6404 * @wiphy: WIPHY structure pointer
6405 * @wdev: Wireless device structure pointer
6406 * @data: Pointer to the data received
6407 * @data_len: Length of the data received
6408 *
6409 * This function is used to enable or disable the collection of packet
6410 * statistics from the firmware
6411 *
6412 * Return: 0 on success and errno on failure
6413 */
6414static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6415 struct wireless_dev *wdev,
6416 const void *data,
6417 int data_len)
6418{
6419 eHalStatus status;
6420 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6421 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6422 tAniWifiStartLog start_log;
6423
6424 status = wlan_hdd_validate_context(hdd_ctx);
6425 if (0 != status) {
6426 return -EINVAL;
6427 }
6428
6429 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6430 data, data_len,
6431 qca_wlan_vendor_wifi_logger_start_policy)) {
6432 hddLog(LOGE, FL("Invalid attribute"));
6433 return -EINVAL;
6434 }
6435
6436 /* Parse and fetch ring id */
6437 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6438 hddLog(LOGE, FL("attr ATTR failed"));
6439 return -EINVAL;
6440 }
6441 start_log.ringId = nla_get_u32(
6442 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6443 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6444
6445 /* Parse and fetch verbose level */
6446 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6447 hddLog(LOGE, FL("attr verbose_level failed"));
6448 return -EINVAL;
6449 }
6450 start_log.verboseLevel = nla_get_u32(
6451 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6452 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6453
6454 /* Parse and fetch flag */
6455 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6456 hddLog(LOGE, FL("attr flag failed"));
6457 return -EINVAL;
6458 }
6459 start_log.flag = nla_get_u32(
6460 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6461 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6462
6463 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306464 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6465 !vos_isPktStatsEnabled()))
6466
Sushant Kaushik8e644982015-09-23 12:18:54 +05306467 {
6468 hddLog(LOGE, FL("per pkt stats not enabled"));
6469 return -EINVAL;
6470 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306471
Sushant Kaushik33200572015-08-05 16:46:20 +05306472 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306473 return 0;
6474}
6475
6476/**
6477 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6478 * or disable the collection of packet statistics from the firmware
6479 * @wiphy: WIPHY structure pointer
6480 * @wdev: Wireless device structure pointer
6481 * @data: Pointer to the data received
6482 * @data_len: Length of the data received
6483 *
6484 * This function is used to enable or disable the collection of packet
6485 * statistics from the firmware
6486 *
6487 * Return: 0 on success and errno on failure
6488 */
6489static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6490 struct wireless_dev *wdev,
6491 const void *data,
6492 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306493{
6494 int ret = 0;
6495
6496 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306497
6498 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6499 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306500 vos_ssr_unprotect(__func__);
6501
6502 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306503}
6504
6505
Agarwal Ashish738843c2014-09-25 12:27:56 +05306506static const struct nla_policy
6507wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6508 +1] =
6509{
6510 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6511};
6512
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306513static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306514 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306515 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306516 int data_len)
6517{
6518 struct net_device *dev = wdev->netdev;
6519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6520 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6522 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6523 eHalStatus status;
6524 u32 dfsFlag = 0;
6525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306526 ENTER();
6527
Agarwal Ashish738843c2014-09-25 12:27:56 +05306528 status = wlan_hdd_validate_context(pHddCtx);
6529 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306530 return -EINVAL;
6531 }
6532 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6533 data, data_len,
6534 wlan_hdd_set_no_dfs_flag_config_policy)) {
6535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6536 return -EINVAL;
6537 }
6538
6539 /* Parse and fetch required bandwidth kbps */
6540 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6542 return -EINVAL;
6543 }
6544
6545 dfsFlag = nla_get_u32(
6546 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6547 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6548 dfsFlag);
6549
6550 pHddCtx->disable_dfs_flag = dfsFlag;
6551
6552 sme_disable_dfs_channel(hHal, dfsFlag);
6553 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306554
6555 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306556 return 0;
6557}
Atul Mittal115287b2014-07-08 13:26:33 +05306558
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306559static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6560 struct wireless_dev *wdev,
6561 const void *data,
6562 int data_len)
6563{
6564 int ret = 0;
6565
6566 vos_ssr_protect(__func__);
6567 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6568 vos_ssr_unprotect(__func__);
6569
6570 return ret;
6571
6572}
6573
Mukul Sharma2a271632014-10-13 14:59:01 +05306574const struct
6575nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6576{
6577 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306578 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6579 .type = NLA_UNSPEC,
6580 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306581};
6582
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306583static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306584 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306585{
6586
6587 u8 bssid[6] = {0};
6588 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6589 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6590 eHalStatus status = eHAL_STATUS_SUCCESS;
6591 v_U32_t isFwrRoamEnabled = FALSE;
6592 int ret;
6593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306594 ENTER();
6595
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306596 ret = wlan_hdd_validate_context(pHddCtx);
6597 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306598 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306599 }
6600
6601 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6602 data, data_len,
6603 qca_wlan_vendor_attr);
6604 if (ret){
6605 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6606 return -EINVAL;
6607 }
6608
6609 /* Parse and fetch Enable flag */
6610 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6612 return -EINVAL;
6613 }
6614
6615 isFwrRoamEnabled = nla_get_u32(
6616 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6617
6618 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6619
6620 /* Parse and fetch bssid */
6621 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6623 return -EINVAL;
6624 }
6625
6626 memcpy(bssid, nla_data(
6627 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6628 sizeof(bssid));
6629 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6630
6631 //Update roaming
6632 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306633 if (!HAL_STATUS_SUCCESS(status)) {
6634 hddLog(LOGE,
6635 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6636 return -EINVAL;
6637 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306638 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306639 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306640}
6641
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306642static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6643 struct wireless_dev *wdev, const void *data, int data_len)
6644{
6645 int ret = 0;
6646
6647 vos_ssr_protect(__func__);
6648 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6649 vos_ssr_unprotect(__func__);
6650
6651 return ret;
6652}
6653
Sushant Kaushik847890c2015-09-28 16:05:17 +05306654static const struct
6655nla_policy
6656qca_wlan_vendor_get_wifi_info_policy[
6657 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6658 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6659 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6660};
6661
6662
6663/**
6664 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6665 * @wiphy: pointer to wireless wiphy structure.
6666 * @wdev: pointer to wireless_dev structure.
6667 * @data: Pointer to the data to be passed via vendor interface
6668 * @data_len:Length of the data to be passed
6669 *
6670 * This is called when wlan driver needs to send wifi driver related info
6671 * (driver/fw version) to the user space application upon request.
6672 *
6673 * Return: Return the Success or Failure code.
6674 */
6675static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6676 struct wireless_dev *wdev,
6677 const void *data, int data_len)
6678{
6679 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6680 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6681 tSirVersionString version;
6682 uint32 version_len;
6683 uint8 attr;
6684 int status;
6685 struct sk_buff *reply_skb = NULL;
6686
6687 if (VOS_FTM_MODE == hdd_get_conparam()) {
6688 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6689 return -EINVAL;
6690 }
6691
6692 status = wlan_hdd_validate_context(hdd_ctx);
6693 if (0 != status) {
6694 hddLog(LOGE, FL("HDD context is not valid"));
6695 return -EINVAL;
6696 }
6697
6698 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6699 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6700 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6701 return -EINVAL;
6702 }
6703
6704 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6705 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6706 QWLAN_VERSIONSTR);
6707 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6708 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6709 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6710 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6711 hdd_ctx->fw_Version);
6712 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6713 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6714 } else {
6715 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6716 return -EINVAL;
6717 }
6718
6719 version_len = strlen(version);
6720 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6721 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6722 if (!reply_skb) {
6723 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6724 return -ENOMEM;
6725 }
6726
6727 if (nla_put(reply_skb, attr, version_len, version)) {
6728 hddLog(LOGE, FL("nla put fail"));
6729 kfree_skb(reply_skb);
6730 return -EINVAL;
6731 }
6732
6733 return cfg80211_vendor_cmd_reply(reply_skb);
6734}
6735
6736/**
6737 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6738 * @wiphy: pointer to wireless wiphy structure.
6739 * @wdev: pointer to wireless_dev structure.
6740 * @data: Pointer to the data to be passed via vendor interface
6741 * @data_len:Length of the data to be passed
6742 * @data_len: Length of the data received
6743 *
6744 * This function is used to enable or disable the collection of packet
6745 * statistics from the firmware
6746 *
6747 * Return: 0 on success and errno on failure
6748 */
6749
6750static int
6751wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6752 struct wireless_dev *wdev,
6753 const void *data, int data_len)
6754
6755
6756{
6757 int ret = 0;
6758
6759 vos_ssr_protect(__func__);
6760 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6761 wdev, data, data_len);
6762 vos_ssr_unprotect(__func__);
6763
6764 return ret;
6765}
6766
6767
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306768/*
6769 * define short names for the global vendor params
6770 * used by __wlan_hdd_cfg80211_monitor_rssi()
6771 */
6772#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6773#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6774#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6775#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6776#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6777
6778/**---------------------------------------------------------------------------
6779
6780 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6781 monitor start is completed successfully.
6782
6783 \return - None
6784
6785 --------------------------------------------------------------------------*/
6786void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6787{
6788 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6789
6790 if (NULL == pHddCtx)
6791 {
6792 hddLog(VOS_TRACE_LEVEL_ERROR,
6793 "%s: HDD context is NULL",__func__);
6794 return;
6795 }
6796
6797 if (VOS_STATUS_SUCCESS == status)
6798 {
6799 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6800 }
6801 else
6802 {
6803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6804 }
6805
6806 return;
6807}
6808
6809/**---------------------------------------------------------------------------
6810
6811 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6812 stop is completed successfully.
6813
6814 \return - None
6815
6816 --------------------------------------------------------------------------*/
6817void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6818{
6819 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6820
6821 if (NULL == pHddCtx)
6822 {
6823 hddLog(VOS_TRACE_LEVEL_ERROR,
6824 "%s: HDD context is NULL",__func__);
6825 return;
6826 }
6827
6828 if (VOS_STATUS_SUCCESS == status)
6829 {
6830 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6831 }
6832 else
6833 {
6834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6835 }
6836
6837 return;
6838}
6839
6840/**
6841 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6842 * @wiphy: Pointer to wireless phy
6843 * @wdev: Pointer to wireless device
6844 * @data: Pointer to data
6845 * @data_len: Data length
6846 *
6847 * Return: 0 on success, negative errno on failure
6848 */
6849
6850static int
6851__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6852 struct wireless_dev *wdev,
6853 const void *data,
6854 int data_len)
6855{
6856 struct net_device *dev = wdev->netdev;
6857 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6858 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6859 hdd_station_ctx_t *pHddStaCtx;
6860 struct nlattr *tb[PARAM_MAX + 1];
6861 tpSirRssiMonitorReq pReq;
6862 eHalStatus status;
6863 int ret;
6864 uint32_t control;
6865 static const struct nla_policy policy[PARAM_MAX + 1] = {
6866 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6867 [PARAM_CONTROL] = { .type = NLA_U32 },
6868 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6869 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6870 };
6871
6872 ENTER();
6873
6874 ret = wlan_hdd_validate_context(hdd_ctx);
6875 if (0 != ret) {
6876 return -EINVAL;
6877 }
6878
6879 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6880 hddLog(LOGE, FL("Not in Connected state!"));
6881 return -ENOTSUPP;
6882 }
6883
6884 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6885 hddLog(LOGE, FL("Invalid ATTR"));
6886 return -EINVAL;
6887 }
6888
6889 if (!tb[PARAM_REQUEST_ID]) {
6890 hddLog(LOGE, FL("attr request id failed"));
6891 return -EINVAL;
6892 }
6893
6894 if (!tb[PARAM_CONTROL]) {
6895 hddLog(LOGE, FL("attr control failed"));
6896 return -EINVAL;
6897 }
6898
6899 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6900
6901 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6902 if(NULL == pReq)
6903 {
6904 hddLog(LOGE,
6905 FL("vos_mem_alloc failed "));
6906 return eHAL_STATUS_FAILED_ALLOC;
6907 }
6908 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6909
6910 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6911 pReq->sessionId = pAdapter->sessionId;
6912 pReq->rssiMonitorCbContext = hdd_ctx;
6913 control = nla_get_u32(tb[PARAM_CONTROL]);
6914 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6915
6916 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6917 pReq->requestId, pReq->sessionId, control);
6918
6919 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6920 if (!tb[PARAM_MIN_RSSI]) {
6921 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306922 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306923 }
6924
6925 if (!tb[PARAM_MAX_RSSI]) {
6926 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306927 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306928 }
6929
6930 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6931 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6932 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6933
6934 if (!(pReq->minRssi < pReq->maxRssi)) {
6935 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6936 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306937 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306938 }
6939 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6940 pReq->minRssi, pReq->maxRssi);
6941 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6942
6943 }
6944 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6945 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6946 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6947 }
6948 else {
6949 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306950 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306951 }
6952
6953 if (!HAL_STATUS_SUCCESS(status)) {
6954 hddLog(LOGE,
6955 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306956 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306957 }
6958
6959 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306960fail:
6961 vos_mem_free(pReq);
6962 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306963}
6964
6965/*
6966 * done with short names for the global vendor params
6967 * used by __wlan_hdd_cfg80211_monitor_rssi()
6968 */
6969#undef PARAM_MAX
6970#undef PARAM_CONTROL
6971#undef PARAM_REQUEST_ID
6972#undef PARAM_MAX_RSSI
6973#undef PARAM_MIN_RSSI
6974
6975/**
6976 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6977 * @wiphy: wiphy structure pointer
6978 * @wdev: Wireless device structure pointer
6979 * @data: Pointer to the data received
6980 * @data_len: Length of @data
6981 *
6982 * Return: 0 on success; errno on failure
6983 */
6984static int
6985wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6986 const void *data, int data_len)
6987{
6988 int ret;
6989
6990 vos_ssr_protect(__func__);
6991 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6992 vos_ssr_unprotect(__func__);
6993
6994 return ret;
6995}
6996
6997/**
6998 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6999 * @hddctx: HDD context
7000 * @data: rssi breached event data
7001 *
7002 * This function reads the rssi breached event %data and fill in the skb with
7003 * NL attributes and send up the NL event.
7004 * This callback execute in atomic context and must not invoke any
7005 * blocking calls.
7006 *
7007 * Return: none
7008 */
7009void hdd_rssi_threshold_breached_cb(void *hddctx,
7010 struct rssi_breach_event *data)
7011{
7012 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7013 int status;
7014 struct sk_buff *skb;
7015
7016 ENTER();
7017 status = wlan_hdd_validate_context(pHddCtx);
7018
7019 if (0 != status) {
7020 return;
7021 }
7022
7023 if (!data) {
7024 hddLog(LOGE, FL("data is null"));
7025 return;
7026 }
7027
7028 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7029#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7030 NULL,
7031#endif
7032 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7033 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7034 GFP_KERNEL);
7035
7036 if (!skb) {
7037 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7038 return;
7039 }
7040
7041 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7042 data->request_id, data->curr_rssi);
7043 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7044 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7045
7046 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7047 data->request_id) ||
7048 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7049 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7050 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7051 data->curr_rssi)) {
7052 hddLog(LOGE, FL("nla put fail"));
7053 goto fail;
7054 }
7055
7056 cfg80211_vendor_event(skb, GFP_KERNEL);
7057 return;
7058
7059fail:
7060 kfree_skb(skb);
7061 return;
7062}
7063
7064
7065
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307066/**
7067 * __wlan_hdd_cfg80211_setband() - set band
7068 * @wiphy: Pointer to wireless phy
7069 * @wdev: Pointer to wireless device
7070 * @data: Pointer to data
7071 * @data_len: Data length
7072 *
7073 * Return: 0 on success, negative errno on failure
7074 */
7075static int
7076__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7077 struct wireless_dev *wdev,
7078 const void *data,
7079 int data_len)
7080{
7081 struct net_device *dev = wdev->netdev;
7082 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7083 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7084 int ret;
7085 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7086 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7087
7088 ENTER();
7089
7090 ret = wlan_hdd_validate_context(hdd_ctx);
7091 if (0 != ret) {
7092 hddLog(LOGE, FL("HDD context is not valid"));
7093 return ret;
7094 }
7095
7096 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7097 policy)) {
7098 hddLog(LOGE, FL("Invalid ATTR"));
7099 return -EINVAL;
7100 }
7101
7102 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7103 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7104 return -EINVAL;
7105 }
7106
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307107 hdd_ctx->isSetBandByNL = TRUE;
7108 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307109 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307110 hdd_ctx->isSetBandByNL = FALSE;
7111
7112 EXIT();
7113 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307114}
7115
7116/**
7117 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7118 * @wiphy: wiphy structure pointer
7119 * @wdev: Wireless device structure pointer
7120 * @data: Pointer to the data received
7121 * @data_len: Length of @data
7122 *
7123 * Return: 0 on success; errno on failure
7124 */
7125static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7126 struct wireless_dev *wdev,
7127 const void *data,
7128 int data_len)
7129{
7130 int ret = 0;
7131
7132 vos_ssr_protect(__func__);
7133 ret = __wlan_hdd_cfg80211_setband(wiphy,
7134 wdev, data, data_len);
7135 vos_ssr_unprotect(__func__);
7136
7137 return ret;
7138}
7139
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307140#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7141/**
7142 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7143 * @hdd_ctx: HDD context
7144 * @request_id: [input] request id
7145 * @pattern_id: [output] pattern id
7146 *
7147 * This function loops through request id to pattern id array
7148 * if the slot is available, store the request id and return pattern id
7149 * if entry exists, return the pattern id
7150 *
7151 * Return: 0 on success and errno on failure
7152 */
7153static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7154 uint32_t request_id,
7155 uint8_t *pattern_id)
7156{
7157 uint32_t i;
7158
7159 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7160 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7161 {
7162 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7163 {
7164 hdd_ctx->op_ctx.op_table[i].request_id = 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 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7169 request_id) {
7170 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7171 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7172 return 0;
7173 }
7174 }
7175 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7176 return -EINVAL;
7177}
7178
7179/**
7180 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7181 * @hdd_ctx: HDD context
7182 * @request_id: [input] request id
7183 * @pattern_id: [output] pattern id
7184 *
7185 * This function loops through request id to pattern id array
7186 * reset request id to 0 (slot available again) and
7187 * return pattern id
7188 *
7189 * Return: 0 on success and errno on failure
7190 */
7191static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7192 uint32_t request_id,
7193 uint8_t *pattern_id)
7194{
7195 uint32_t i;
7196
7197 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7198 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7199 {
7200 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7201 {
7202 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7203 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7204 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7205 return 0;
7206 }
7207 }
7208 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7209 return -EINVAL;
7210}
7211
7212
7213/*
7214 * define short names for the global vendor params
7215 * used by __wlan_hdd_cfg80211_offloaded_packets()
7216 */
7217#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7218#define PARAM_REQUEST_ID \
7219 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7220#define PARAM_CONTROL \
7221 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7222#define PARAM_IP_PACKET \
7223 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7224#define PARAM_SRC_MAC_ADDR \
7225 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7226#define PARAM_DST_MAC_ADDR \
7227 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7228#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7229
7230/**
7231 * wlan_hdd_add_tx_ptrn() - add tx pattern
7232 * @adapter: adapter pointer
7233 * @hdd_ctx: hdd context
7234 * @tb: nl attributes
7235 *
7236 * This function reads the NL attributes and forms a AddTxPtrn message
7237 * posts it to SME.
7238 *
7239 */
7240static int
7241wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7242 struct nlattr **tb)
7243{
7244 struct sSirAddPeriodicTxPtrn *add_req;
7245 eHalStatus status;
7246 uint32_t request_id, ret, len;
7247 uint8_t pattern_id = 0;
7248 v_MACADDR_t dst_addr;
7249 uint16_t eth_type = htons(ETH_P_IP);
7250
7251 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7252 {
7253 hddLog(LOGE, FL("Not in Connected state!"));
7254 return -ENOTSUPP;
7255 }
7256
7257 add_req = vos_mem_malloc(sizeof(*add_req));
7258 if (!add_req)
7259 {
7260 hddLog(LOGE, FL("memory allocation failed"));
7261 return -ENOMEM;
7262 }
7263
7264 /* Parse and fetch request Id */
7265 if (!tb[PARAM_REQUEST_ID])
7266 {
7267 hddLog(LOGE, FL("attr request id failed"));
7268 goto fail;
7269 }
7270
7271 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7272 hddLog(LOG1, FL("Request Id: %u"), request_id);
7273 if (request_id == 0)
7274 {
7275 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307276 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307277 }
7278
7279 if (!tb[PARAM_PERIOD])
7280 {
7281 hddLog(LOGE, FL("attr period failed"));
7282 goto fail;
7283 }
7284 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7285 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7286 if (add_req->usPtrnIntervalMs == 0)
7287 {
7288 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7289 goto fail;
7290 }
7291
7292 if (!tb[PARAM_SRC_MAC_ADDR])
7293 {
7294 hddLog(LOGE, FL("attr source mac address failed"));
7295 goto fail;
7296 }
7297 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7298 VOS_MAC_ADDR_SIZE);
7299 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7300 MAC_ADDR_ARRAY(add_req->macAddress));
7301
7302 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7303 VOS_MAC_ADDR_SIZE))
7304 {
7305 hddLog(LOGE,
7306 FL("input src mac address and connected ap bssid are different"));
7307 goto fail;
7308 }
7309
7310 if (!tb[PARAM_DST_MAC_ADDR])
7311 {
7312 hddLog(LOGE, FL("attr dst mac address failed"));
7313 goto fail;
7314 }
7315 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7316 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7317 MAC_ADDR_ARRAY(dst_addr.bytes));
7318
7319 if (!tb[PARAM_IP_PACKET])
7320 {
7321 hddLog(LOGE, FL("attr ip packet failed"));
7322 goto fail;
7323 }
7324 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7325 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7326
7327 if (add_req->ucPtrnSize < 0 ||
7328 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7329 HDD_ETH_HEADER_LEN))
7330 {
7331 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7332 add_req->ucPtrnSize);
7333 goto fail;
7334 }
7335
7336 len = 0;
7337 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7338 len += VOS_MAC_ADDR_SIZE;
7339 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7340 VOS_MAC_ADDR_SIZE);
7341 len += VOS_MAC_ADDR_SIZE;
7342 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7343 len += 2;
7344
7345 /*
7346 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7347 * ------------------------------------------------------------
7348 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7349 * ------------------------------------------------------------
7350 */
7351 vos_mem_copy(&add_req->ucPattern[len],
7352 nla_data(tb[PARAM_IP_PACKET]),
7353 add_req->ucPtrnSize);
7354 add_req->ucPtrnSize += len;
7355
7356 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7357 add_req->ucPattern, add_req->ucPtrnSize);
7358
7359 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7360 if (ret)
7361 {
7362 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7363 goto fail;
7364 }
7365 add_req->ucPtrnId = pattern_id;
7366 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7367
7368 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7369 if (!HAL_STATUS_SUCCESS(status))
7370 {
7371 hddLog(LOGE,
7372 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7373 goto fail;
7374 }
7375
7376 EXIT();
7377 vos_mem_free(add_req);
7378 return 0;
7379
7380fail:
7381 vos_mem_free(add_req);
7382 return -EINVAL;
7383}
7384
7385/**
7386 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7387 * @adapter: adapter pointer
7388 * @hdd_ctx: hdd context
7389 * @tb: nl attributes
7390 *
7391 * This function reads the NL attributes and forms a DelTxPtrn message
7392 * posts it to SME.
7393 *
7394 */
7395static int
7396wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7397 struct nlattr **tb)
7398{
7399 struct sSirDelPeriodicTxPtrn *del_req;
7400 eHalStatus status;
7401 uint32_t request_id, ret;
7402 uint8_t pattern_id = 0;
7403
7404 /* Parse and fetch request Id */
7405 if (!tb[PARAM_REQUEST_ID])
7406 {
7407 hddLog(LOGE, FL("attr request id failed"));
7408 return -EINVAL;
7409 }
7410 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7411 if (request_id == 0)
7412 {
7413 hddLog(LOGE, FL("request_id cannot be zero"));
7414 return -EINVAL;
7415 }
7416
7417 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7418 if (ret)
7419 {
7420 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7421 return -EINVAL;
7422 }
7423
7424 del_req = vos_mem_malloc(sizeof(*del_req));
7425 if (!del_req)
7426 {
7427 hddLog(LOGE, FL("memory allocation failed"));
7428 return -ENOMEM;
7429 }
7430
7431 vos_mem_set(del_req, sizeof(*del_req), 0);
7432 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7433 VOS_MAC_ADDR_SIZE);
7434 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7435 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7436 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7437 request_id, pattern_id, del_req->ucPatternIdBitmap);
7438
7439 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7440 if (!HAL_STATUS_SUCCESS(status))
7441 {
7442 hddLog(LOGE,
7443 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7444 goto fail;
7445 }
7446
7447 EXIT();
7448 vos_mem_free(del_req);
7449 return 0;
7450
7451fail:
7452 vos_mem_free(del_req);
7453 return -EINVAL;
7454}
7455
7456
7457/**
7458 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7459 * @wiphy: Pointer to wireless phy
7460 * @wdev: Pointer to wireless device
7461 * @data: Pointer to data
7462 * @data_len: Data length
7463 *
7464 * Return: 0 on success, negative errno on failure
7465 */
7466static int
7467__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7468 struct wireless_dev *wdev,
7469 const void *data,
7470 int data_len)
7471{
7472 struct net_device *dev = wdev->netdev;
7473 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7474 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7475 struct nlattr *tb[PARAM_MAX + 1];
7476 uint8_t control;
7477 int ret;
7478 static const struct nla_policy policy[PARAM_MAX + 1] =
7479 {
7480 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7481 [PARAM_CONTROL] = { .type = NLA_U32 },
7482 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7483 .len = VOS_MAC_ADDR_SIZE },
7484 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7485 .len = VOS_MAC_ADDR_SIZE },
7486 [PARAM_PERIOD] = { .type = NLA_U32 },
7487 };
7488
7489 ENTER();
7490
7491 ret = wlan_hdd_validate_context(hdd_ctx);
7492 if (0 != ret)
7493 {
7494 hddLog(LOGE, FL("HDD context is not valid"));
7495 return ret;
7496 }
7497
7498 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7499 {
7500 hddLog(LOGE,
7501 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7502 return -ENOTSUPP;
7503 }
7504
7505 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7506 {
7507 hddLog(LOGE, FL("Invalid ATTR"));
7508 return -EINVAL;
7509 }
7510
7511 if (!tb[PARAM_CONTROL])
7512 {
7513 hddLog(LOGE, FL("attr control failed"));
7514 return -EINVAL;
7515 }
7516 control = nla_get_u32(tb[PARAM_CONTROL]);
7517 hddLog(LOG1, FL("Control: %d"), control);
7518
7519 if (control == WLAN_START_OFFLOADED_PACKETS)
7520 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7521 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7522 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7523 else
7524 {
7525 hddLog(LOGE, FL("Invalid control: %d"), control);
7526 return -EINVAL;
7527 }
7528}
7529
7530/*
7531 * done with short names for the global vendor params
7532 * used by __wlan_hdd_cfg80211_offloaded_packets()
7533 */
7534#undef PARAM_MAX
7535#undef PARAM_REQUEST_ID
7536#undef PARAM_CONTROL
7537#undef PARAM_IP_PACKET
7538#undef PARAM_SRC_MAC_ADDR
7539#undef PARAM_DST_MAC_ADDR
7540#undef PARAM_PERIOD
7541
7542/**
7543 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7544 * @wiphy: wiphy structure pointer
7545 * @wdev: Wireless device structure pointer
7546 * @data: Pointer to the data received
7547 * @data_len: Length of @data
7548 *
7549 * Return: 0 on success; errno on failure
7550 */
7551static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7552 struct wireless_dev *wdev,
7553 const void *data,
7554 int data_len)
7555{
7556 int ret = 0;
7557
7558 vos_ssr_protect(__func__);
7559 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7560 wdev, data, data_len);
7561 vos_ssr_unprotect(__func__);
7562
7563 return ret;
7564}
7565#endif
7566
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307567static const struct
7568nla_policy
7569qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307570 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7571 .type = NLA_BINARY,
7572 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307573};
7574
7575/**
7576 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7577 * get link properties like nss, rate flags and operating frequency for
7578 * the connection with the given peer.
7579 * @wiphy: WIPHY structure pointer
7580 * @wdev: Wireless device structure pointer
7581 * @data: Pointer to the data received
7582 * @data_len: Length of the data received
7583 *
7584 * This function return the above link properties on success.
7585 *
7586 * Return: 0 on success and errno on failure
7587 */
7588static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7589 struct wireless_dev *wdev,
7590 const void *data,
7591 int data_len)
7592{
7593 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7594 struct net_device *dev = wdev->netdev;
7595 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7596 hdd_station_ctx_t *hdd_sta_ctx;
7597 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7598 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7599 uint32_t sta_id;
7600 struct sk_buff *reply_skb;
7601 uint32_t rate_flags = 0;
7602 uint8_t nss;
7603 uint8_t final_rate_flags = 0;
7604 uint32_t freq;
7605 v_CONTEXT_t pVosContext = NULL;
7606 ptSapContext pSapCtx = NULL;
7607
7608 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7610 return -EINVAL;
7611 }
7612
7613 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7614 qca_wlan_vendor_attr_policy)) {
7615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7616 return -EINVAL;
7617 }
7618
7619 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7620 hddLog(VOS_TRACE_LEVEL_ERROR,
7621 FL("Attribute peerMac not provided for mode=%d"),
7622 adapter->device_mode);
7623 return -EINVAL;
7624 }
7625
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307626 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7627 hddLog(VOS_TRACE_LEVEL_ERROR,
7628 FL("Attribute peerMac is invalid=%d"),
7629 adapter->device_mode);
7630 return -EINVAL;
7631 }
7632
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307633 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7634 sizeof(peer_mac));
7635 hddLog(VOS_TRACE_LEVEL_INFO,
7636 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7637 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7638
7639 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7640 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7641 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7642 if ((hdd_sta_ctx->conn_info.connState !=
7643 eConnectionState_Associated) ||
7644 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7645 VOS_MAC_ADDRESS_LEN)) {
7646 hddLog(VOS_TRACE_LEVEL_ERROR,
7647 FL("Not Associated to mac "MAC_ADDRESS_STR),
7648 MAC_ADDR_ARRAY(peer_mac));
7649 return -EINVAL;
7650 }
7651
7652 nss = 1; //pronto supports only one spatial stream
7653 freq = vos_chan_to_freq(
7654 hdd_sta_ctx->conn_info.operationChannel);
7655 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7656
7657 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7658 adapter->device_mode == WLAN_HDD_SOFTAP) {
7659
7660 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7661 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7662 if(pSapCtx == NULL){
7663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7664 FL("psapCtx is NULL"));
7665 return -ENOENT;
7666 }
7667
7668
7669 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7670 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7671 !vos_is_macaddr_broadcast(
7672 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7673 vos_mem_compare(
7674 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7675 peer_mac, VOS_MAC_ADDRESS_LEN))
7676 break;
7677 }
7678
7679 if (WLAN_MAX_STA_COUNT == sta_id) {
7680 hddLog(VOS_TRACE_LEVEL_ERROR,
7681 FL("No active peer with mac="MAC_ADDRESS_STR),
7682 MAC_ADDR_ARRAY(peer_mac));
7683 return -EINVAL;
7684 }
7685
7686 nss = 1; //pronto supports only one spatial stream
7687 freq = vos_chan_to_freq(
7688 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7689 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7690 } else {
7691 hddLog(VOS_TRACE_LEVEL_ERROR,
7692 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7693 MAC_ADDR_ARRAY(peer_mac));
7694 return -EINVAL;
7695 }
7696
7697 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7698 if (rate_flags & eHAL_TX_RATE_VHT80) {
7699 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307700#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7701 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307702 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307703#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307704 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7705 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307706#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7707 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307708 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307709#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307710 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7711 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7712 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7713 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307714#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7715 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307716 if (rate_flags & eHAL_TX_RATE_HT40)
7717 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307718#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307719 }
7720
7721 if (rate_flags & eHAL_TX_RATE_SGI) {
7722 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7723 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7724 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7725 }
7726 }
7727
7728 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7729 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7730
7731 if (NULL == reply_skb) {
7732 hddLog(VOS_TRACE_LEVEL_ERROR,
7733 FL("getLinkProperties: skb alloc failed"));
7734 return -EINVAL;
7735 }
7736
7737 if (nla_put_u8(reply_skb,
7738 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7739 nss) ||
7740 nla_put_u8(reply_skb,
7741 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7742 final_rate_flags) ||
7743 nla_put_u32(reply_skb,
7744 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7745 freq)) {
7746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7747 kfree_skb(reply_skb);
7748 return -EINVAL;
7749 }
7750
7751 return cfg80211_vendor_cmd_reply(reply_skb);
7752}
7753
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307754#define BEACON_MISS_THRESH_2_4 \
7755 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7756#define BEACON_MISS_THRESH_5_0 \
7757 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307758#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7759#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7760#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7761#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307762#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7763 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307764#define PARAM_FORCE_RSN_IE \
7765 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307766/*
7767 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7768 * @hdd_ctx: hdd context
7769 * @enable: Value received in the command, 1 for disable and 2 for enable
7770 *
7771 * Return: void
7772 */
7773static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7774{
7775 if (!hdd_ctx) {
7776 hddLog(LOGE, "hdd_ctx NULL");
7777 return;
7778 }
7779
7780 sme_set_qpower(hdd_ctx->hHal, enable);
7781}
7782
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307783/**
7784 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7785 * vendor command
7786 *
7787 * @wiphy: wiphy device pointer
7788 * @wdev: wireless device pointer
7789 * @data: Vendor command data buffer
7790 * @data_len: Buffer length
7791 *
7792 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7793 *
7794 * Return: EOK or other error codes.
7795 */
7796
7797static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7798 struct wireless_dev *wdev,
7799 const void *data,
7800 int data_len)
7801{
7802 struct net_device *dev = wdev->netdev;
7803 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7804 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7805 hdd_station_ctx_t *pHddStaCtx;
7806 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7807 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307808 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307809 eHalStatus status;
7810 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307811 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307812 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307813
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307814 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7815 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7816 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307817 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7818 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7819 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307820 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7821 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307822 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307823 };
7824
7825 ENTER();
7826
7827 if (VOS_FTM_MODE == hdd_get_conparam()) {
7828 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7829 return -EINVAL;
7830 }
7831
7832 ret_val = wlan_hdd_validate_context(pHddCtx);
7833 if (ret_val) {
7834 return ret_val;
7835 }
7836
7837 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7838
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7840 hddLog(LOGE, FL("Invalid ATTR"));
7841 return -EINVAL;
7842 }
7843
7844 /* check the Wifi Capability */
7845 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7846 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7847 {
7848 hddLog(VOS_TRACE_LEVEL_ERROR,
7849 FL("WIFICONFIG not supported by Firmware"));
7850 return -EINVAL;
7851 }
7852
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307853 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7854 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7855 modifyRoamParamsReq.value =
7856 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7857
7858 if (eHAL_STATUS_SUCCESS !=
7859 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7860 {
7861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7862 ret_val = -EINVAL;
7863 }
7864 return ret_val;
7865 }
7866
7867 /* Moved this down in order to provide provision to set beacon
7868 * miss penalty count irrespective of connection state.
7869 */
7870 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7871 hddLog(LOGE, FL("Not in Connected state!"));
7872 return -ENOTSUPP;
7873 }
7874
7875 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307876
7877 if (!pReq) {
7878 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7879 "%s: Not able to allocate memory for tSetWifiConfigParams",
7880 __func__);
7881 return eHAL_STATUS_E_MALLOC_FAILED;
7882 }
7883
7884 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7885
7886 pReq->sessionId = pAdapter->sessionId;
7887 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7888
7889 if (tb[PARAM_MODULATED_DTIM]) {
7890 pReq->paramValue = nla_get_u32(
7891 tb[PARAM_MODULATED_DTIM]);
7892 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7893 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307894 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307895 hdd_set_pwrparams(pHddCtx);
7896 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7897 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7898
7899 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7900 iw_full_power_cbfn, pAdapter,
7901 eSME_FULL_PWR_NEEDED_BY_HDD);
7902 }
7903 else
7904 {
7905 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7906 }
7907 }
7908
7909 if (tb[PARAM_STATS_AVG_FACTOR]) {
7910 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7911 pReq->paramValue = nla_get_u16(
7912 tb[PARAM_STATS_AVG_FACTOR]);
7913 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7914 pReq->paramType, pReq->paramValue);
7915 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7916
7917 if (eHAL_STATUS_SUCCESS != status)
7918 {
7919 vos_mem_free(pReq);
7920 pReq = NULL;
7921 ret_val = -EPERM;
7922 return ret_val;
7923 }
7924 }
7925
7926
7927 if (tb[PARAM_GUARD_TIME]) {
7928 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7929 pReq->paramValue = nla_get_u32(
7930 tb[PARAM_GUARD_TIME]);
7931 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7932 pReq->paramType, pReq->paramValue);
7933 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7934
7935 if (eHAL_STATUS_SUCCESS != status)
7936 {
7937 vos_mem_free(pReq);
7938 pReq = NULL;
7939 ret_val = -EPERM;
7940 return ret_val;
7941 }
7942
7943 }
7944
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307945 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7946 hb_thresh_val = nla_get_u8(
7947 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7948
7949 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7950 hb_thresh_val);
7951 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7952 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7953 NULL, eANI_BOOLEAN_FALSE);
7954
7955 status = sme_update_hb_threshold(
7956 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7957 WNI_CFG_HEART_BEAT_THRESHOLD,
7958 hb_thresh_val, eCSR_BAND_24);
7959 if (eHAL_STATUS_SUCCESS != status) {
7960 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7961 vos_mem_free(pReq);
7962 pReq = NULL;
7963 return -EPERM;
7964 }
7965 }
7966
7967 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7968 hb_thresh_val = nla_get_u8(
7969 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7970
7971 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7972 hb_thresh_val);
7973 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7974 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7975 NULL, eANI_BOOLEAN_FALSE);
7976
7977 status = sme_update_hb_threshold(
7978 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7979 WNI_CFG_HEART_BEAT_THRESHOLD,
7980 hb_thresh_val, eCSR_BAND_5G);
7981 if (eHAL_STATUS_SUCCESS != status) {
7982 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7983 vos_mem_free(pReq);
7984 pReq = NULL;
7985 return -EPERM;
7986 }
7987 }
7988
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307989 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
7990 qpower = nla_get_u8(
7991 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
7992
7993 if(qpower > 1) {
7994 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
7995 vos_mem_free(pReq);
7996 pReq = NULL;
7997 return -EINVAL;
7998 }
7999 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8000 qpower++;
8001 hdd_set_qpower(pHddCtx, qpower);
8002 }
8003
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308004 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8005 pHddCtx->cfg_ini->force_rsne_override) {
8006 uint8_t force_rsne_override;
8007
8008 force_rsne_override =
8009 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8010 if (force_rsne_override > 1) {
8011 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8012 ret_val = -EINVAL;
8013 }
8014 pHddCtx->force_rsne_override = force_rsne_override;
8015 hddLog(LOG1, "force_rsne_override - %d",
8016 pHddCtx->force_rsne_override);
8017 }
8018
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308019 EXIT();
8020 return ret_val;
8021}
8022
8023/**
8024 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8025 * vendor command
8026 *
8027 * @wiphy: wiphy device pointer
8028 * @wdev: wireless device pointer
8029 * @data: Vendor command data buffer
8030 * @data_len: Buffer length
8031 *
8032 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8033 *
8034 * Return: EOK or other error codes.
8035 */
8036static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8037 struct wireless_dev *wdev,
8038 const void *data,
8039 int data_len)
8040{
8041 int ret;
8042
8043 vos_ssr_protect(__func__);
8044 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8045 data, data_len);
8046 vos_ssr_unprotect(__func__);
8047
8048 return ret;
8049}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308050
8051/*
8052 * define short names for the global vendor params
8053 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8054 */
8055#define STATS_SET_INVALID \
8056 QCA_ATTR_NUD_STATS_SET_INVALID
8057#define STATS_SET_START \
8058 QCA_ATTR_NUD_STATS_SET_START
8059#define STATS_GW_IPV4 \
8060 QCA_ATTR_NUD_STATS_GW_IPV4
8061#define STATS_SET_MAX \
8062 QCA_ATTR_NUD_STATS_SET_MAX
8063
8064const struct nla_policy
8065qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8066{
8067 [STATS_SET_START] = {.type = NLA_FLAG },
8068 [STATS_GW_IPV4] = {.type = NLA_U32 },
8069};
8070
8071/**
8072 * hdd_set_nud_stats_cb() - hdd callback api to get status
8073 * @data: pointer to adapter
8074 * @rsp: status
8075 *
8076 * Return: None
8077 */
8078static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8079{
8080
8081 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8082
8083 if (NULL == adapter)
8084 return;
8085
8086 if (VOS_STATUS_SUCCESS == rsp) {
8087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8088 "%s success received STATS_SET_START", __func__);
8089 } else {
8090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8091 "%s STATS_SET_START Failed!!", __func__);
8092 }
8093 return;
8094}
8095
8096/**
8097 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8098 * @wiphy: pointer to wireless wiphy structure.
8099 * @wdev: pointer to wireless_dev structure.
8100 * @data: pointer to apfind configuration data.
8101 * @data_len: the length in byte of apfind data.
8102 *
8103 * This is called when wlan driver needs to send arp stats to
8104 * firmware.
8105 *
8106 * Return: An error code or 0 on success.
8107 */
8108static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8109 struct wireless_dev *wdev,
8110 const void *data, int data_len)
8111{
8112 struct nlattr *tb[STATS_SET_MAX + 1];
8113 struct net_device *dev = wdev->netdev;
8114 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8115 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308116 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308117 setArpStatsParams arp_stats_params;
8118 int err = 0;
8119
8120 ENTER();
8121
8122 err = wlan_hdd_validate_context(hdd_ctx);
8123 if (0 != err)
8124 return err;
8125
8126 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8128 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8129 return -EINVAL;
8130 }
8131
8132 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8133 qca_wlan_vendor_set_nud_stats);
8134 if (err)
8135 {
8136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8137 "%s STATS_SET_START ATTR", __func__);
8138 return err;
8139 }
8140
8141 if (tb[STATS_SET_START])
8142 {
8143 if (!tb[STATS_GW_IPV4]) {
8144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8145 "%s STATS_SET_START CMD", __func__);
8146 return -EINVAL;
8147 }
8148 arp_stats_params.flag = true;
8149 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8150 } else {
8151 arp_stats_params.flag = false;
8152 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308153 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8155 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308156 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8157 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308158
8159 arp_stats_params.pkt_type = 1; // ARP packet type
8160
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308161 if (arp_stats_params.flag) {
8162 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8163 WLANTL_SetARPFWDatapath(pVosContext, true);
8164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8165 "%s Set FW in data path for ARP with tgt IP :%d",
8166 __func__, hdd_ctx->track_arp_ip);
8167 }
8168 else {
8169 WLANTL_SetARPFWDatapath(pVosContext, false);
8170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8171 "%s Remove FW from data path", __func__);
8172 }
8173
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308174 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8175 arp_stats_params.data_ctx = adapter;
8176
8177 if (eHAL_STATUS_SUCCESS !=
8178 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8180 "%s STATS_SET_START CMD Failed!!", __func__);
8181 return -EINVAL;
8182 }
8183
8184 EXIT();
8185
8186 return err;
8187}
8188
8189/**
8190 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8191 * @wiphy: pointer to wireless wiphy structure.
8192 * @wdev: pointer to wireless_dev structure.
8193 * @data: pointer to apfind configuration data.
8194 * @data_len: the length in byte of apfind data.
8195 *
8196 * This is called when wlan driver needs to send arp stats to
8197 * firmware.
8198 *
8199 * Return: An error code or 0 on success.
8200 */
8201static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8202 struct wireless_dev *wdev,
8203 const void *data, int data_len)
8204{
8205 int ret;
8206
8207 vos_ssr_protect(__func__);
8208 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8209 vos_ssr_unprotect(__func__);
8210
8211 return ret;
8212}
8213#undef STATS_SET_INVALID
8214#undef STATS_SET_START
8215#undef STATS_GW_IPV4
8216#undef STATS_SET_MAX
8217
8218/*
8219 * define short names for the global vendor params
8220 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8221 */
8222#define STATS_GET_INVALID \
8223 QCA_ATTR_NUD_STATS_SET_INVALID
8224#define COUNT_FROM_NETDEV \
8225 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8226#define COUNT_TO_LOWER_MAC \
8227 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8228#define RX_COUNT_BY_LOWER_MAC \
8229 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8230#define COUNT_TX_SUCCESS \
8231 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8232#define RSP_RX_COUNT_BY_LOWER_MAC \
8233 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8234#define RSP_RX_COUNT_BY_UPPER_MAC \
8235 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8236#define RSP_COUNT_TO_NETDEV \
8237 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8238#define RSP_COUNT_OUT_OF_ORDER_DROP \
8239 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8240#define AP_LINK_ACTIVE \
8241 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8242#define AP_LINK_DAD \
8243 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8244#define STATS_GET_MAX \
8245 QCA_ATTR_NUD_STATS_GET_MAX
8246
8247const struct nla_policy
8248qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8249{
8250 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8251 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8252 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8253 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8254 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8255 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8256 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8257 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8258 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8259 [AP_LINK_DAD] = {.type = NLA_FLAG },
8260};
8261
8262static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8263{
8264
8265 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308266 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308267 struct hdd_nud_stats_context *context;
8268 int status;
8269
8270 ENTER();
8271
8272 if (NULL == adapter)
8273 return;
8274
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308275 if (!rsp) {
8276 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308277 return;
8278 }
8279
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308280 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8281 status = wlan_hdd_validate_context(hdd_ctx);
8282 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308283 return;
8284 }
8285
8286 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8287 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8288 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8289 adapter->dad |= rsp->dad;
8290
8291 spin_lock(&hdd_context_lock);
8292 context = &hdd_ctx->nud_stats_context;
8293 complete(&context->response_event);
8294 spin_unlock(&hdd_context_lock);
8295
8296 return;
8297}
8298static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8299 struct wireless_dev *wdev,
8300 const void *data, int data_len)
8301{
8302 int err = 0;
8303 unsigned long rc;
8304 struct hdd_nud_stats_context *context;
8305 struct net_device *dev = wdev->netdev;
8306 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8307 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8308 getArpStatsParams arp_stats_params;
8309 struct sk_buff *skb;
8310
8311 ENTER();
8312
8313 err = wlan_hdd_validate_context(hdd_ctx);
8314 if (0 != err)
8315 return err;
8316
8317 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8318 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8319 arp_stats_params.data_ctx = adapter;
8320
8321 spin_lock(&hdd_context_lock);
8322 context = &hdd_ctx->nud_stats_context;
8323 INIT_COMPLETION(context->response_event);
8324 spin_unlock(&hdd_context_lock);
8325
8326 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8328 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8329 return -EINVAL;
8330 }
8331
8332 if (eHAL_STATUS_SUCCESS !=
8333 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8335 "%s STATS_SET_START CMD Failed!!", __func__);
8336 return -EINVAL;
8337 }
8338
8339 rc = wait_for_completion_timeout(&context->response_event,
8340 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8341 if (!rc)
8342 {
8343 hddLog(LOGE,
8344 FL("Target response timed out request "));
8345 return -ETIMEDOUT;
8346 }
8347
8348 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8349 WLAN_NUD_STATS_LEN);
8350 if (!skb)
8351 {
8352 hddLog(VOS_TRACE_LEVEL_ERROR,
8353 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8354 __func__);
8355 return -ENOMEM;
8356 }
8357
8358 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8359 adapter->hdd_stats.hddArpStats.txCount) ||
8360 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8361 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8362 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8363 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8364 nla_put_u16(skb, COUNT_TX_SUCCESS,
8365 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8366 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8367 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8368 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8369 adapter->hdd_stats.hddArpStats.rxCount) ||
8370 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8371 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8372 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8373 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8374 hddLog(LOGE, FL("nla put fail"));
8375 kfree_skb(skb);
8376 return -EINVAL;
8377 }
8378 if (adapter->con_status)
8379 nla_put_flag(skb, AP_LINK_ACTIVE);
8380 if (adapter->dad)
8381 nla_put_flag(skb, AP_LINK_DAD);
8382
8383 cfg80211_vendor_cmd_reply(skb);
8384 return err;
8385}
8386
8387static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8388 struct wireless_dev *wdev,
8389 const void *data, int data_len)
8390{
8391 int ret;
8392
8393 vos_ssr_protect(__func__);
8394 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8395 vos_ssr_unprotect(__func__);
8396
8397 return ret;
8398}
8399
8400#undef QCA_ATTR_NUD_STATS_SET_INVALID
8401#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8402#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8403#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8404#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8405#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8406#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8407#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8408#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8409#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8410#undef QCA_ATTR_NUD_STATS_GET_MAX
8411
8412
8413
Kapil Guptaee33bf12016-12-20 18:27:37 +05308414#ifdef WLAN_FEATURE_APFIND
8415/**
8416 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8417 * @wiphy: pointer to wireless wiphy structure.
8418 * @wdev: pointer to wireless_dev structure.
8419 * @data: pointer to apfind configuration data.
8420 * @data_len: the length in byte of apfind data.
8421 *
8422 * This is called when wlan driver needs to send APFIND configurations to
8423 * firmware.
8424 *
8425 * Return: An error code or 0 on success.
8426 */
8427static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8428 struct wireless_dev *wdev,
8429 const void *data, int data_len)
8430{
8431 struct sme_ap_find_request_req apfind_req;
8432 VOS_STATUS status;
8433 int ret_val;
8434 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8435
8436 ENTER();
8437
8438 ret_val = wlan_hdd_validate_context(hdd_ctx);
8439 if (ret_val)
8440 return ret_val;
8441
8442 if (VOS_FTM_MODE == hdd_get_conparam()) {
8443 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8444 return -EPERM;
8445 }
8446
8447 apfind_req.request_data_len = data_len;
8448 apfind_req.request_data = data;
8449
8450 status = sme_apfind_set_cmd(&apfind_req);
8451 if (VOS_STATUS_SUCCESS != status) {
8452 ret_val = -EIO;
8453 }
8454 return ret_val;
8455}
8456
8457/**
8458 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8459 * @wiphy: pointer to wireless wiphy structure.
8460 * @wdev: pointer to wireless_dev structure.
8461 * @data: pointer to apfind configuration data.
8462 * @data_len: the length in byte of apfind data.
8463 *
8464 * This is called when wlan driver needs to send APFIND configurations to
8465 * firmware.
8466 *
8467 * Return: An error code or 0 on success.
8468 */
8469static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8470 struct wireless_dev *wdev,
8471 const void *data, int data_len)
8472{
8473 int ret;
8474
8475 vos_ssr_protect(__func__);
8476 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8477 vos_ssr_unprotect(__func__);
8478
8479 return ret;
8480}
8481#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308482
8483/**
8484 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8485 * @wiphy: pointer to wireless wiphy structure.
8486 * @wdev: pointer to wireless_dev structure.
8487 * @data: Pointer to the data to be passed via vendor interface
8488 * @data_len:Length of the data to be passed
8489 *
8490 * This is called by userspace to know the supported logger features
8491 *
8492 * Return: Return the Success or Failure code.
8493 */
8494static int
8495__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8496 struct wireless_dev *wdev,
8497 const void *data, int data_len)
8498{
8499 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8500 int status;
8501 uint32_t features;
8502 struct sk_buff *reply_skb = NULL;
8503
8504 if (VOS_FTM_MODE == hdd_get_conparam()) {
8505 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8506 return -EINVAL;
8507 }
8508
8509 status = wlan_hdd_validate_context(hdd_ctx);
8510 if (0 != status)
8511 return -EINVAL;
8512
8513 features = 0;
8514
8515 if (hdd_is_memdump_supported())
8516 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8517
8518 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8519 hdd_ctx->cfg_ini->enableFatalEvent &&
8520 hdd_ctx->is_fatal_event_log_sup) {
8521 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8522 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8523 }
8524
8525 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8526 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8527 if (!reply_skb) {
8528 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8529 return -ENOMEM;
8530 }
8531
8532 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8533 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8534 features)) {
8535 hddLog(LOGE, FL("nla put fail"));
8536 kfree_skb(reply_skb);
8537 return -EINVAL;
8538 }
8539
8540 return cfg80211_vendor_cmd_reply(reply_skb);
8541}
8542
8543/**
8544 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8545 * @wiphy: pointer to wireless wiphy structure.
8546 * @wdev: pointer to wireless_dev structure.
8547 * @data: Pointer to the data to be passed via vendor interface
8548 * @data_len:Length of the data to be passed
8549 *
8550 * This is called by userspace to know the supported logger features
8551 *
8552 * Return: Return the Success or Failure code.
8553 */
8554static int
8555wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8556 struct wireless_dev *wdev,
8557 const void *data, int data_len)
8558{
8559 int ret;
8560
8561 vos_ssr_protect(__func__);
8562 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8563 data, data_len);
8564 vos_ssr_unprotect(__func__);
8565
8566 return ret;
8567}
8568
Sunil Duttc69bccb2014-05-26 21:30:20 +05308569const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8570{
Mukul Sharma2a271632014-10-13 14:59:01 +05308571 {
8572 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8573 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8574 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8575 WIPHY_VENDOR_CMD_NEED_NETDEV |
8576 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308577 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308578 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308579
8580 {
8581 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8582 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8583 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8584 WIPHY_VENDOR_CMD_NEED_NETDEV |
8585 WIPHY_VENDOR_CMD_NEED_RUNNING,
8586 .doit = wlan_hdd_cfg80211_nan_request
8587 },
8588
Sunil Duttc69bccb2014-05-26 21:30:20 +05308589#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8590 {
8591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8594 WIPHY_VENDOR_CMD_NEED_NETDEV |
8595 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308596 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308597 },
8598
8599 {
8600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8603 WIPHY_VENDOR_CMD_NEED_NETDEV |
8604 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308605 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308606 },
8607
8608 {
8609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8612 WIPHY_VENDOR_CMD_NEED_NETDEV |
8613 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308614 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308615 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308616#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308617#ifdef WLAN_FEATURE_EXTSCAN
8618 {
8619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8622 WIPHY_VENDOR_CMD_NEED_NETDEV |
8623 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308624 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308625 },
8626 {
8627 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8628 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8629 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8630 WIPHY_VENDOR_CMD_NEED_NETDEV |
8631 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308632 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308633 },
8634 {
8635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8638 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308639 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308640 },
8641 {
8642 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8643 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8644 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8645 WIPHY_VENDOR_CMD_NEED_NETDEV |
8646 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308647 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308648 },
8649 {
8650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8652 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8653 WIPHY_VENDOR_CMD_NEED_NETDEV |
8654 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308655 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308656 },
8657 {
8658 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8659 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8660 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8661 WIPHY_VENDOR_CMD_NEED_NETDEV |
8662 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308663 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308664 },
8665 {
8666 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8667 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8668 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8669 WIPHY_VENDOR_CMD_NEED_NETDEV |
8670 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308671 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308672 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308673#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308674/*EXT TDLS*/
8675 {
8676 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8677 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8679 WIPHY_VENDOR_CMD_NEED_NETDEV |
8680 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308681 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308682 },
8683 {
8684 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8685 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8686 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8687 WIPHY_VENDOR_CMD_NEED_NETDEV |
8688 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308689 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308690 },
8691 {
8692 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8693 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8694 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8695 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308696 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308697 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308698 {
8699 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8700 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8701 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8702 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308703 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308704 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308705 {
8706 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8707 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8708 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8709 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308710 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308711 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308712 {
8713 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8714 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8715 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8716 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308717 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308718 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308724 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308725 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308726 {
8727 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308728 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8729 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8730 WIPHY_VENDOR_CMD_NEED_NETDEV |
8731 WIPHY_VENDOR_CMD_NEED_RUNNING,
8732 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8733 },
8734 {
8735 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308736 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8737 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8738 WIPHY_VENDOR_CMD_NEED_NETDEV |
8739 WIPHY_VENDOR_CMD_NEED_RUNNING,
8740 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308741 },
8742 {
8743 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8744 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8745 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8746 WIPHY_VENDOR_CMD_NEED_NETDEV,
8747 .doit = wlan_hdd_cfg80211_wifi_logger_start
8748 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308749 {
8750 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8751 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8752 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8753 WIPHY_VENDOR_CMD_NEED_NETDEV|
8754 WIPHY_VENDOR_CMD_NEED_RUNNING,
8755 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308756 },
8757 {
8758 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8759 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8760 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8761 WIPHY_VENDOR_CMD_NEED_NETDEV |
8762 WIPHY_VENDOR_CMD_NEED_RUNNING,
8763 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308764 },
8765 {
8766 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8767 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8768 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8769 WIPHY_VENDOR_CMD_NEED_NETDEV |
8770 WIPHY_VENDOR_CMD_NEED_RUNNING,
8771 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308772 },
8773#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8774 {
8775 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8776 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8777 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8778 WIPHY_VENDOR_CMD_NEED_NETDEV |
8779 WIPHY_VENDOR_CMD_NEED_RUNNING,
8780 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308781 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308782#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308783 {
8784 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8785 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8786 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8787 WIPHY_VENDOR_CMD_NEED_NETDEV |
8788 WIPHY_VENDOR_CMD_NEED_RUNNING,
8789 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308790 },
8791 {
8792 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8793 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8794 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8795 WIPHY_VENDOR_CMD_NEED_NETDEV |
8796 WIPHY_VENDOR_CMD_NEED_RUNNING,
8797 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308798 },
8799#ifdef WLAN_FEATURE_APFIND
8800 {
8801 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8802 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8803 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8804 WIPHY_VENDOR_CMD_NEED_NETDEV,
8805 .doit = wlan_hdd_cfg80211_apfind_cmd
8806 },
8807#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308808 {
8809 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8810 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8811 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8812 WIPHY_VENDOR_CMD_NEED_NETDEV |
8813 WIPHY_VENDOR_CMD_NEED_RUNNING,
8814 .doit = wlan_hdd_cfg80211_set_nud_stats
8815 },
8816 {
8817 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8818 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8819 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8820 WIPHY_VENDOR_CMD_NEED_NETDEV |
8821 WIPHY_VENDOR_CMD_NEED_RUNNING,
8822 .doit = wlan_hdd_cfg80211_get_nud_stats
8823 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308824 {
8825 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8826 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8827 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8828 WIPHY_VENDOR_CMD_NEED_NETDEV |
8829 WIPHY_VENDOR_CMD_NEED_RUNNING,
8830 .doit = hdd_cfg80211_get_station_cmd
8831 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308832 {
8833 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8834 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8835 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308836 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308837 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8838 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308839};
8840
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008841/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308842static const
8843struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008844{
8845#ifdef FEATURE_WLAN_CH_AVOID
8846 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308847 .vendor_id = QCA_NL80211_VENDOR_ID,
8848 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008849 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308850#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8851#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8852 {
8853 /* Index = 1*/
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8856 },
8857 {
8858 /* Index = 2*/
8859 .vendor_id = QCA_NL80211_VENDOR_ID,
8860 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8861 },
8862 {
8863 /* Index = 3*/
8864 .vendor_id = QCA_NL80211_VENDOR_ID,
8865 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8866 },
8867 {
8868 /* Index = 4*/
8869 .vendor_id = QCA_NL80211_VENDOR_ID,
8870 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8871 },
8872 {
8873 /* Index = 5*/
8874 .vendor_id = QCA_NL80211_VENDOR_ID,
8875 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8876 },
8877 {
8878 /* Index = 6*/
8879 .vendor_id = QCA_NL80211_VENDOR_ID,
8880 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8881 },
8882#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308883#ifdef WLAN_FEATURE_EXTSCAN
8884 {
8885 .vendor_id = QCA_NL80211_VENDOR_ID,
8886 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8887 },
8888 {
8889 .vendor_id = QCA_NL80211_VENDOR_ID,
8890 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8891 },
8892 {
8893 .vendor_id = QCA_NL80211_VENDOR_ID,
8894 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8895 },
8896 {
8897 .vendor_id = QCA_NL80211_VENDOR_ID,
8898 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8899 },
8900 {
8901 .vendor_id = QCA_NL80211_VENDOR_ID,
8902 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8903 },
8904 {
8905 .vendor_id = QCA_NL80211_VENDOR_ID,
8906 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8907 },
8908 {
8909 .vendor_id = QCA_NL80211_VENDOR_ID,
8910 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8911 },
8912 {
8913 .vendor_id = QCA_NL80211_VENDOR_ID,
8914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8915 },
8916 {
8917 .vendor_id = QCA_NL80211_VENDOR_ID,
8918 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8919 },
8920 {
8921 .vendor_id = QCA_NL80211_VENDOR_ID,
8922 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8923 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308924#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308925/*EXT TDLS*/
8926 {
8927 .vendor_id = QCA_NL80211_VENDOR_ID,
8928 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8929 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308930 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8931 .vendor_id = QCA_NL80211_VENDOR_ID,
8932 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8933 },
8934
Srinivas Dasari030bad32015-02-18 23:23:54 +05308935
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308936 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8939 },
8940
Sushant Kaushik084f6592015-09-10 13:11:56 +05308941 {
8942 .vendor_id = QCA_NL80211_VENDOR_ID,
8943 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308944 },
8945 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8946 .vendor_id = QCA_NL80211_VENDOR_ID,
8947 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8948 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308949 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8950 .vendor_id = QCA_NL80211_VENDOR_ID,
8951 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8952 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308953 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8954 .vendor_id = QCA_NL80211_VENDOR_ID,
8955 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8956 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308957 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8958 .vendor_id = QCA_NL80211_VENDOR_ID,
8959 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8960 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308961 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8962 .vendor_id = QCA_NL80211_VENDOR_ID,
8963 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8964 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008965};
8966
Jeff Johnson295189b2012-06-20 16:38:30 -07008967/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308968 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308969 * This function is called by hdd_wlan_startup()
8970 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308971 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308973struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008974{
8975 struct wiphy *wiphy;
8976 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308977 /*
8978 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008979 */
8980 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8981
8982 if (!wiphy)
8983 {
8984 /* Print error and jump into err label and free the memory */
8985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8986 return NULL;
8987 }
8988
Sunil Duttc69bccb2014-05-26 21:30:20 +05308989
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 return wiphy;
8991}
8992
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308993#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8994 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8995/**
8996 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8997 * @wiphy: pointer to wiphy
8998 * @config: pointer to config
8999 *
9000 * Return: None
9001 */
9002static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9003 hdd_config_t *config)
9004{
9005 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9006 if (config->max_sched_scan_plan_interval)
9007 wiphy->max_sched_scan_plan_interval =
9008 config->max_sched_scan_plan_interval;
9009 if (config->max_sched_scan_plan_iterations)
9010 wiphy->max_sched_scan_plan_iterations =
9011 config->max_sched_scan_plan_iterations;
9012}
9013#else
9014static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9015 hdd_config_t *config)
9016{
9017}
9018#endif
9019
Jeff Johnson295189b2012-06-20 16:38:30 -07009020/*
9021 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309022 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 * private ioctl to change the band value
9024 */
9025int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9026{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309027 int i, j;
9028 eNVChannelEnabledType channelEnabledState;
9029
Jeff Johnsone7245742012-09-05 17:12:55 -07009030 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309031
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309032 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309034
9035 if (NULL == wiphy->bands[i])
9036 {
9037 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9038 __func__, i);
9039 continue;
9040 }
9041
9042 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9043 {
9044 struct ieee80211_supported_band *band = wiphy->bands[i];
9045
9046 channelEnabledState = vos_nv_getChannelEnabledState(
9047 band->channels[j].hw_value);
9048
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309049 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309050 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309051 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309052 continue;
9053 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309054 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309055 {
9056 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9057 continue;
9058 }
9059
9060 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9061 NV_CHANNEL_INVALID == channelEnabledState)
9062 {
9063 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9064 }
9065 else if (NV_CHANNEL_DFS == channelEnabledState)
9066 {
9067 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9068 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9069 }
9070 else
9071 {
9072 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9073 |IEEE80211_CHAN_RADAR);
9074 }
9075 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 }
9077 return 0;
9078}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309079
9080/**
9081 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9082 * @wiphy: Pointer to the wiphy.
9083 *
9084 * This Function adds Channel Switch support flag, if channel switch is
9085 * supported by kernel.
9086 * Return: void.
9087 */
9088#ifdef CHANNEL_SWITCH_SUPPORTED
9089static inline
9090void hdd_add_channel_switch_support(struct wiphy *wiphy)
9091{
9092 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9093 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9094}
9095#else
9096static inline
9097void hdd_add_channel_switch_support(struct wiphy *wiphy)
9098{
9099}
9100#endif
9101
Jeff Johnson295189b2012-06-20 16:38:30 -07009102/*
9103 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309104 * This function is called by hdd_wlan_startup()
9105 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 * This function is used to initialize and register wiphy structure.
9107 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309108int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 struct wiphy *wiphy,
9110 hdd_config_t *pCfg
9111 )
9112{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309113 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309114 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9115
Jeff Johnsone7245742012-09-05 17:12:55 -07009116 ENTER();
9117
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 /* Now bind the underlying wlan device with wiphy */
9119 set_wiphy_dev(wiphy, dev);
9120
9121 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009122
Kiet Lam6c583332013-10-14 05:37:09 +05309123#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009124 /* the flag for the other case would be initialzed in
9125 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9127 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9128#else
Amar Singhal0a402232013-10-11 20:57:16 -07009129 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309130#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309131#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009132
Amar Singhalfddc28c2013-09-05 13:03:40 -07009133 /* This will disable updating of NL channels from passive to
9134 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309135#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9136 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9137#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009138 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309139#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009140
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9142 wiphy->wowlan = &wowlan_support_cfg80211_init;
9143#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309144 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9145 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309146 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9147 wiphy->wowlan.pattern_min_len = 1;
9148 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9149#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009150
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009152 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9153 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9154 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009155 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309156#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309157 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309158#else
9159 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9160#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009161#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009162
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009163#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009164 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009165#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009166 || pCfg->isFastRoamIniFeatureEnabled
9167#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009168#ifdef FEATURE_WLAN_ESE
9169 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009170#endif
9171 )
9172 {
9173 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9174 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009175#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009176#ifdef FEATURE_WLAN_TDLS
9177 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9178 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9179#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309180#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309181 if (pCfg->configPNOScanSupport)
9182 {
9183 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9184 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9185 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9186 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9187 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309188#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009189
Abhishek Singh10d85972015-04-17 10:27:23 +05309190#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9191 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9192#endif
9193
Amar Singhalfddc28c2013-09-05 13:03:40 -07009194#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009195 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9196 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009197 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009198 driver need to determine what to do with both
9199 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009200
9201 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009202#else
9203 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009204#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009205
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309206 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9207
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309208 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009209
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309210 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9211
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309213 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9214 | BIT(NL80211_IFTYPE_ADHOC)
9215 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9216 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309217 | BIT(NL80211_IFTYPE_AP)
9218 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009219
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309220 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009221 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9223 if( pCfg->enableMCC )
9224 {
9225 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309226 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009227
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309228 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309229 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009230
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309231 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309232 wiphy->iface_combinations = wlan_hdd_iface_combination;
9233 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009234#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309235 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009236
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 /* Before registering we need to update the ht capabilitied based
9238 * on ini values*/
9239 if( !pCfg->ShortGI20MhzEnable )
9240 {
9241 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9242 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 }
9244
9245 if( !pCfg->ShortGI40MhzEnable )
9246 {
9247 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9248 }
9249
9250 if( !pCfg->nChannelBondingMode5GHz )
9251 {
9252 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9253 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309254 /*
9255 * In case of static linked driver at the time of driver unload,
9256 * module exit doesn't happens. Module cleanup helps in cleaning
9257 * of static memory.
9258 * If driver load happens statically, at the time of driver unload,
9259 * wiphy flags don't get reset because of static memory.
9260 * It's better not to store channel in static memory.
9261 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309262 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9263 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309264 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309265 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309266 {
9267 hddLog(VOS_TRACE_LEVEL_ERROR,
9268 FL("Not enough memory to allocate channels"));
9269 return -ENOMEM;
9270 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309271 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309272 &hdd_channels_2_4_GHZ[0],
9273 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009274
Agrawal Ashish97dec502015-11-26 20:20:58 +05309275 if (true == hdd_is_5g_supported(pHddCtx))
9276 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309277 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9278 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309279 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309280 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309281 {
9282 hddLog(VOS_TRACE_LEVEL_ERROR,
9283 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309284 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9285 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309286 return -ENOMEM;
9287 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309288 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309289 &hdd_channels_5_GHZ[0],
9290 sizeof(hdd_channels_5_GHZ));
9291 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309292
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309293 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309294 {
9295
9296 if (NULL == wiphy->bands[i])
9297 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309298 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309299 __func__, i);
9300 continue;
9301 }
9302
9303 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9304 {
9305 struct ieee80211_supported_band *band = wiphy->bands[i];
9306
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309307 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309308 {
9309 // Enable social channels for P2P
9310 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9311 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9312 else
9313 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9314 continue;
9315 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309316 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309317 {
9318 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9319 continue;
9320 }
9321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 }
9323 /*Initialise the supported cipher suite details*/
9324 wiphy->cipher_suites = hdd_cipher_suites;
9325 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9326
9327 /*signal strength in mBm (100*dBm) */
9328 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9329
9330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309331 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009332#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009333
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309334 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309335 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9336 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009337 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9338 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9339
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309340 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9341
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309342 EXIT();
9343 return 0;
9344}
9345
9346/* In this function we are registering wiphy. */
9347int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9348{
9349 ENTER();
9350 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 if (0 > wiphy_register(wiphy))
9352 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309353 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9355 return -EIO;
9356 }
9357
9358 EXIT();
9359 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309360}
Jeff Johnson295189b2012-06-20 16:38:30 -07009361
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309362/* In this function we are updating channel list when,
9363 regulatory domain is FCC and country code is US.
9364 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9365 As per FCC smart phone is not a indoor device.
9366 GO should not opeate on indoor channels */
9367void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9368{
9369 int j;
9370 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9371 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9372 //Default counrtycode from NV at the time of wiphy initialization.
9373 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9374 &defaultCountryCode[0]))
9375 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009376 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309377 }
9378 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9379 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309380 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309381 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309382 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309383 return;
9384 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309385 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309386 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309387 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309388 // Mark UNII -1 band channel as passive
9389 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9390 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9391 }
9392 }
9393}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309394/* This function registers for all frame which supplicant is interested in */
9395void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009396{
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9398 /* Register for all P2P action, public action etc frames */
9399 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009400 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309401 /* Register frame indication call back */
9402 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 /* Right now we are registering these frame when driver is getting
9404 initialized. Once we will move to 2.6.37 kernel, in which we have
9405 frame register ops, we will move this code as a part of that */
9406 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309407 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9409
9410 /* GAS Initial Response */
9411 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9412 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309413
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 /* GAS Comeback Request */
9415 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9416 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9417
9418 /* GAS Comeback Response */
9419 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9420 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9421
9422 /* P2P Public Action */
9423 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309424 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 P2P_PUBLIC_ACTION_FRAME_SIZE );
9426
9427 /* P2P Action */
9428 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9429 (v_U8_t*)P2P_ACTION_FRAME,
9430 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009431
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309432 /* WNM BSS Transition Request frame */
9433 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9434 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9435 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009436
9437 /* WNM-Notification */
9438 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9439 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9440 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009441}
9442
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309443void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009444{
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9446 /* Register for all P2P action, public action etc frames */
9447 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9448
Jeff Johnsone7245742012-09-05 17:12:55 -07009449 ENTER();
9450
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 /* Right now we are registering these frame when driver is getting
9452 initialized. Once we will move to 2.6.37 kernel, in which we have
9453 frame register ops, we will move this code as a part of that */
9454 /* GAS Initial Request */
9455
9456 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9457 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9458
9459 /* GAS Initial Response */
9460 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9461 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 /* GAS Comeback Request */
9464 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9465 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9466
9467 /* GAS Comeback Response */
9468 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9469 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9470
9471 /* P2P Public Action */
9472 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309473 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 P2P_PUBLIC_ACTION_FRAME_SIZE );
9475
9476 /* P2P Action */
9477 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9478 (v_U8_t*)P2P_ACTION_FRAME,
9479 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009480 /* WNM-Notification */
9481 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9482 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9483 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009484}
9485
9486#ifdef FEATURE_WLAN_WAPI
9487void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309488 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009489{
9490 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9491 tCsrRoamSetKey setKey;
9492 v_BOOL_t isConnected = TRUE;
9493 int status = 0;
9494 v_U32_t roamId= 0xFF;
9495 tANI_U8 *pKeyPtr = NULL;
9496 int n = 0;
9497
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9499 __func__, hdd_device_modetoString(pAdapter->device_mode),
9500 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009501
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309502 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 setKey.keyId = key_index; // Store Key ID
9504 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9505 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9506 setKey.paeRole = 0 ; // the PAE role
9507 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9508 {
9509 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9510 }
9511 else
9512 {
9513 isConnected = hdd_connIsConnected(pHddStaCtx);
9514 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9515 }
9516 setKey.keyLength = key_Len;
9517 pKeyPtr = setKey.Key;
9518 memcpy( pKeyPtr, key, key_Len);
9519
Arif Hussain6d2a3322013-11-17 19:50:10 -08009520 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009521 __func__, key_Len);
9522 for (n = 0 ; n < key_Len; n++)
9523 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9524 __func__,n,setKey.Key[n]);
9525
9526 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9527 if ( isConnected )
9528 {
9529 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9530 pAdapter->sessionId, &setKey, &roamId );
9531 }
9532 if ( status != 0 )
9533 {
9534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9535 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9536 __LINE__, status );
9537 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9538 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309539 /* Need to clear any trace of key value in the memory.
9540 * Thus zero out the memory even though it is local
9541 * variable.
9542 */
9543 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009544}
9545#endif /* FEATURE_WLAN_WAPI*/
9546
9547#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309548int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009549 beacon_data_t **ppBeacon,
9550 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009551#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009553 beacon_data_t **ppBeacon,
9554 struct cfg80211_beacon_data *params,
9555 int dtim_period)
9556#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557{
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 int size;
9559 beacon_data_t *beacon = NULL;
9560 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309561 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9562 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009563
Jeff Johnsone7245742012-09-05 17:12:55 -07009564 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309566 {
9567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9568 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309570 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009571
9572 old = pAdapter->sessionCtx.ap.beacon;
9573
9574 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309575 {
9576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9577 FL("session(%d) old and new heads points to NULL"),
9578 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309580 }
9581
9582 if (params->tail && !params->tail_len)
9583 {
9584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9585 FL("tail_len is zero but tail is not NULL"));
9586 return -EINVAL;
9587 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9590 /* Kernel 3.0 is not updating dtim_period for set beacon */
9591 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309592 {
9593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9594 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309596 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009597#endif
9598
Kapil Gupta137ef892016-12-13 19:38:00 +05309599 if (params->head)
9600 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309602 head = params->head;
9603 } else
9604 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309606 head = old->head;
9607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009608
Kapil Gupta137ef892016-12-13 19:38:00 +05309609 if (params->tail || !old)
9610 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309612 tail = params->tail;
9613 } else
9614 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309616 tail = old->tail;
9617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009618
Kapil Gupta137ef892016-12-13 19:38:00 +05309619 if (params->proberesp_ies || !old)
9620 {
9621 proberesp_ies_len = params->proberesp_ies_len;
9622 proberesp_ies = params->proberesp_ies;
9623 } else
9624 {
9625 proberesp_ies_len = old->proberesp_ies_len;
9626 proberesp_ies = old->proberesp_ies;
9627 }
9628
9629 if (params->assocresp_ies || !old)
9630 {
9631 assocresp_ies_len = params->assocresp_ies_len;
9632 assocresp_ies = params->assocresp_ies;
9633 } else
9634 {
9635 assocresp_ies_len = old->assocresp_ies_len;
9636 assocresp_ies = old->assocresp_ies;
9637 }
9638
9639 size = sizeof(beacon_data_t) + head_len + tail_len +
9640 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009641
9642 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309644 {
9645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9646 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009649
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009650#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309651 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 beacon->dtim_period = params->dtim_period;
9653 else
9654 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009655#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309656 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009657 beacon->dtim_period = dtim_period;
9658 else
9659 beacon->dtim_period = old->dtim_period;
9660#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9663 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309664 beacon->proberesp_ies = beacon->tail + tail_len;
9665 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9666
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 beacon->head_len = head_len;
9668 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309669 beacon->proberesp_ies_len = proberesp_ies_len;
9670 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
c_manjee527ecac2017-01-25 12:25:27 +05309672 if (head && head_len)
9673 memcpy(beacon->head, head, head_len);
9674 if (tail && tail_len)
9675 memcpy(beacon->tail, tail, tail_len);
9676 if (proberesp_ies && proberesp_ies_len)
9677 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9678 if (assocresp_ies && assocresp_ies_len)
9679 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009680
9681 *ppBeacon = beacon;
9682
9683 kfree(old);
9684
9685 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009686}
Jeff Johnson295189b2012-06-20 16:38:30 -07009687
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309688v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9690 const v_U8_t *pIes,
9691#else
9692 v_U8_t *pIes,
9693#endif
9694 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009695{
9696 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309697 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309699
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309701 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 elem_id = ptr[0];
9703 elem_len = ptr[1];
9704 left -= 2;
9705 if(elem_len > left)
9706 {
9707 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009708 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 eid,elem_len,left);
9710 return NULL;
9711 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309712 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 {
9714 return ptr;
9715 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309716
Jeff Johnson295189b2012-06-20 16:38:30 -07009717 left -= elem_len;
9718 ptr += (elem_len + 2);
9719 }
9720 return NULL;
9721}
9722
Jeff Johnson295189b2012-06-20 16:38:30 -07009723/* Check if rate is 11g rate or not */
9724static int wlan_hdd_rate_is_11g(u8 rate)
9725{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009726 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 u8 i;
9728 for (i = 0; i < 8; i++)
9729 {
9730 if(rate == gRateArray[i])
9731 return TRUE;
9732 }
9733 return FALSE;
9734}
9735
9736/* Check for 11g rate and set proper 11g only mode */
9737static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9738 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9739{
9740 u8 i, num_rates = pIe[0];
9741
9742 pIe += 1;
9743 for ( i = 0; i < num_rates; i++)
9744 {
9745 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9746 {
9747 /* If rate set have 11g rate than change the mode to 11G */
9748 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9749 if (pIe[i] & BASIC_RATE_MASK)
9750 {
9751 /* If we have 11g rate as basic rate, it means mode
9752 is 11g only mode.
9753 */
9754 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9755 *pCheckRatesfor11g = FALSE;
9756 }
9757 }
9758 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9759 {
9760 *require_ht = TRUE;
9761 }
9762 }
9763 return;
9764}
9765
9766static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9767{
9768 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9769 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9770 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9771 u8 checkRatesfor11g = TRUE;
9772 u8 require_ht = FALSE;
9773 u8 *pIe=NULL;
9774
9775 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9776
9777 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9778 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9779 if (pIe != NULL)
9780 {
9781 pIe += 1;
9782 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9783 &pConfig->SapHw_mode);
9784 }
9785
9786 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9787 WLAN_EID_EXT_SUPP_RATES);
9788 if (pIe != NULL)
9789 {
9790
9791 pIe += 1;
9792 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9793 &pConfig->SapHw_mode);
9794 }
9795
9796 if( pConfig->channel > 14 )
9797 {
9798 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9799 }
9800
9801 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9802 WLAN_EID_HT_CAPABILITY);
9803
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309804 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 {
9806 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9807 if(require_ht)
9808 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9809 }
9810}
9811
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309812static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9813 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9814{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009815 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309816 v_U8_t *pIe = NULL;
9817 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9818
9819 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9820 pBeacon->tail, pBeacon->tail_len);
9821
9822 if (pIe)
9823 {
9824 ielen = pIe[1] + 2;
9825 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9826 {
9827 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9828 }
9829 else
9830 {
9831 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9832 return -EINVAL;
9833 }
9834 *total_ielen += ielen;
9835 }
9836 return 0;
9837}
9838
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009839static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9840 v_U8_t *genie, v_U8_t *total_ielen)
9841{
9842 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9843 int left = pBeacon->tail_len;
9844 v_U8_t *ptr = pBeacon->tail;
9845 v_U8_t elem_id, elem_len;
9846 v_U16_t ielen = 0;
9847
9848 if ( NULL == ptr || 0 == left )
9849 return;
9850
9851 while (left >= 2)
9852 {
9853 elem_id = ptr[0];
9854 elem_len = ptr[1];
9855 left -= 2;
9856 if (elem_len > left)
9857 {
9858 hddLog( VOS_TRACE_LEVEL_ERROR,
9859 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9860 elem_id, elem_len, left);
9861 return;
9862 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309863 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009864 {
9865 /* skipping the VSIE's which we don't want to include or
9866 * it will be included by existing code
9867 */
9868 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9869#ifdef WLAN_FEATURE_WFD
9870 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9871#endif
9872 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9873 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9874 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9875 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9876 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9877 {
9878 ielen = ptr[1] + 2;
9879 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9880 {
9881 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9882 *total_ielen += ielen;
9883 }
9884 else
9885 {
9886 hddLog( VOS_TRACE_LEVEL_ERROR,
9887 "IE Length is too big "
9888 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9889 elem_id, elem_len, *total_ielen);
9890 }
9891 }
9892 }
9893
9894 left -= elem_len;
9895 ptr += (elem_len + 2);
9896 }
9897 return;
9898}
9899
Kapil Gupta137ef892016-12-13 19:38:00 +05309900int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009901{
9902 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309903 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009905 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309906 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009907
9908 genie = vos_mem_malloc(MAX_GENIE_LEN);
9909
9910 if(genie == NULL) {
9911
9912 return -ENOMEM;
9913 }
9914
Kapil Gupta137ef892016-12-13 19:38:00 +05309915 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309916 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9917 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309919 hddLog(LOGE,
9920 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309921 ret = -EINVAL;
9922 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 }
9924
9925#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309926 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9927 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9928 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309929 hddLog(LOGE,
9930 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309931 ret = -EINVAL;
9932 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 }
9934#endif
9935
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309936 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9937 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009938 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309939 hddLog(LOGE,
9940 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309941 ret = -EINVAL;
9942 goto done;
9943 }
9944
9945 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9946 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009947 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009948 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009949
9950 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9951 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9952 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9953 {
9954 hddLog(LOGE,
9955 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009956 ret = -EINVAL;
9957 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 }
9959
9960 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9961 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9962 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9963 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9964 ==eHAL_STATUS_FAILURE)
9965 {
9966 hddLog(LOGE,
9967 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009968 ret = -EINVAL;
9969 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 }
9971
9972 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309973 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309975 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 u8 probe_rsp_ie_len[3] = {0};
9977 u8 counter = 0;
9978 /* Check Probe Resp Length if it is greater then 255 then Store
9979 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9980 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9981 Store More then 255 bytes into One Variable.
9982 */
9983 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9984 {
9985 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9986 {
9987 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9988 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9989 }
9990 else
9991 {
9992 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9993 rem_probe_resp_ie_len = 0;
9994 }
9995 }
9996
9997 rem_probe_resp_ie_len = 0;
9998
9999 if (probe_rsp_ie_len[0] > 0)
10000 {
10001 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10002 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010003 (tANI_U8*)&pBeacon->
10004 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 probe_rsp_ie_len[0], NULL,
10006 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10007 {
10008 hddLog(LOGE,
10009 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010010 ret = -EINVAL;
10011 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 }
10013 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10014 }
10015
10016 if (probe_rsp_ie_len[1] > 0)
10017 {
10018 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10019 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010020 (tANI_U8*)&pBeacon->
10021 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 probe_rsp_ie_len[1], NULL,
10023 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10024 {
10025 hddLog(LOGE,
10026 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010027 ret = -EINVAL;
10028 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 }
10030 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10031 }
10032
10033 if (probe_rsp_ie_len[2] > 0)
10034 {
10035 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10036 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010037 (tANI_U8*)&pBeacon->
10038 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 probe_rsp_ie_len[2], NULL,
10040 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10041 {
10042 hddLog(LOGE,
10043 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010044 ret = -EINVAL;
10045 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 }
10047 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10048 }
10049
10050 if (probe_rsp_ie_len[1] == 0 )
10051 {
10052 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10053 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10054 eANI_BOOLEAN_FALSE) )
10055 {
10056 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010057 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010058 }
10059 }
10060
10061 if (probe_rsp_ie_len[2] == 0 )
10062 {
10063 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10064 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10065 eANI_BOOLEAN_FALSE) )
10066 {
10067 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010068 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 }
10070 }
10071
10072 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10073 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10074 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10075 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10076 == eHAL_STATUS_FAILURE)
10077 {
10078 hddLog(LOGE,
10079 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010080 ret = -EINVAL;
10081 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 }
10083 }
10084 else
10085 {
10086 // Reset WNI_CFG_PROBE_RSP Flags
10087 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10088
10089 hddLog(VOS_TRACE_LEVEL_INFO,
10090 "%s: No Probe Response IE received in set beacon",
10091 __func__);
10092 }
10093
10094 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010095 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 {
10097 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010098 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10099 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10101 {
10102 hddLog(LOGE,
10103 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010104 ret = -EINVAL;
10105 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 }
10107
10108 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10109 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10110 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10111 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10112 == eHAL_STATUS_FAILURE)
10113 {
10114 hddLog(LOGE,
10115 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010116 ret = -EINVAL;
10117 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 }
10119 }
10120 else
10121 {
10122 hddLog(VOS_TRACE_LEVEL_INFO,
10123 "%s: No Assoc Response IE received in set beacon",
10124 __func__);
10125
10126 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10127 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10128 eANI_BOOLEAN_FALSE) )
10129 {
10130 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010131 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 }
10133 }
10134
Jeff Johnsone7245742012-09-05 17:12:55 -070010135done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010137 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010138}
Jeff Johnson295189b2012-06-20 16:38:30 -070010139
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010140/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 * FUNCTION: wlan_hdd_validate_operation_channel
10142 * called by wlan_hdd_cfg80211_start_bss() and
10143 * wlan_hdd_cfg80211_set_channel()
10144 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010145 * channel list.
10146 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010147VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010148{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010149
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 v_U32_t num_ch = 0;
10151 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10152 u32 indx = 0;
10153 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010154 v_U8_t fValidChannel = FALSE, count = 0;
10155 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010156
Jeff Johnson295189b2012-06-20 16:38:30 -070010157 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10158
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010159 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010160 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010161 /* Validate the channel */
10162 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010163 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010164 if ( channel == rfChannels[count].channelNum )
10165 {
10166 fValidChannel = TRUE;
10167 break;
10168 }
10169 }
10170 if (fValidChannel != TRUE)
10171 {
10172 hddLog(VOS_TRACE_LEVEL_ERROR,
10173 "%s: Invalid Channel [%d]", __func__, channel);
10174 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 }
10176 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010177 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010179 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10180 valid_ch, &num_ch))
10181 {
10182 hddLog(VOS_TRACE_LEVEL_ERROR,
10183 "%s: failed to get valid channel list", __func__);
10184 return VOS_STATUS_E_FAILURE;
10185 }
10186 for (indx = 0; indx < num_ch; indx++)
10187 {
10188 if (channel == valid_ch[indx])
10189 {
10190 break;
10191 }
10192 }
10193
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010194 if (indx >= num_ch)
10195 {
10196 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10197 {
10198 eCsrBand band;
10199 unsigned int freq;
10200
10201 sme_GetFreqBand(hHal, &band);
10202
10203 if (eCSR_BAND_5G == band)
10204 {
10205#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10206 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10207 {
10208 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010209 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010210 }
10211 else
10212 {
10213 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010214 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010215 }
10216#else
10217 freq = ieee80211_channel_to_frequency(channel);
10218#endif
10219 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10220 return VOS_STATUS_SUCCESS;
10221 }
10222 }
10223
10224 hddLog(VOS_TRACE_LEVEL_ERROR,
10225 "%s: Invalid Channel [%d]", __func__, channel);
10226 return VOS_STATUS_E_FAILURE;
10227 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010229
Jeff Johnson295189b2012-06-20 16:38:30 -070010230 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010231
Jeff Johnson295189b2012-06-20 16:38:30 -070010232}
10233
Viral Modi3a32cc52013-02-08 11:14:52 -080010234/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010235 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010236 * This function is used to set the channel number
10237 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010238static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010239 struct ieee80211_channel *chan,
10240 enum nl80211_channel_type channel_type
10241 )
10242{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010243 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010244 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010245 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010246 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010247 hdd_context_t *pHddCtx;
10248 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010249
10250 ENTER();
10251
10252 if( NULL == dev )
10253 {
10254 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010255 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010256 return -ENODEV;
10257 }
10258 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010259
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010260 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10261 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10262 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010263 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010264 "%s: device_mode = %s (%d) freq = %d", __func__,
10265 hdd_device_modetoString(pAdapter->device_mode),
10266 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010267
10268 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10269 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010270 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010271 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010272 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010273 }
10274
10275 /*
10276 * Do freq to chan conversion
10277 * TODO: for 11a
10278 */
10279
10280 channel = ieee80211_frequency_to_channel(freq);
10281
10282 /* Check freq range */
10283 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10284 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10285 {
10286 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010287 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010288 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10289 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10290 return -EINVAL;
10291 }
10292
10293 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10294
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010295 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10296 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010297 {
10298 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10299 {
10300 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010301 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010302 return -EINVAL;
10303 }
10304 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10305 "%s: set channel to [%d] for device mode =%d",
10306 __func__, channel,pAdapter->device_mode);
10307 }
10308 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010309 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010310 )
10311 {
10312 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10313 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10314 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10315
10316 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10317 {
10318 /* Link is up then return cant set channel*/
10319 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010320 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010321 return -EINVAL;
10322 }
10323
10324 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10325 pHddStaCtx->conn_info.operationChannel = channel;
10326 pRoamProfile->ChannelInfo.ChannelList =
10327 &pHddStaCtx->conn_info.operationChannel;
10328 }
10329 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010330 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010331 )
10332 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010333 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10334 {
10335 if(VOS_STATUS_SUCCESS !=
10336 wlan_hdd_validate_operation_channel(pAdapter,channel))
10337 {
10338 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010339 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010340 return -EINVAL;
10341 }
10342 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10343 }
10344 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010345 {
10346 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10347
10348 /* If auto channel selection is configured as enable/ 1 then ignore
10349 channel set by supplicant
10350 */
10351 if ( cfg_param->apAutoChannelSelection )
10352 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010353 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10354 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010355 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010356 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10357 __func__, hdd_device_modetoString(pAdapter->device_mode),
10358 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010359 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010360 else
10361 {
10362 if(VOS_STATUS_SUCCESS !=
10363 wlan_hdd_validate_operation_channel(pAdapter,channel))
10364 {
10365 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010366 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010367 return -EINVAL;
10368 }
10369 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10370 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010371 }
10372 }
10373 else
10374 {
10375 hddLog(VOS_TRACE_LEVEL_FATAL,
10376 "%s: Invalid device mode failed to set valid channel", __func__);
10377 return -EINVAL;
10378 }
10379 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010380 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010381}
10382
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010383static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10384 struct net_device *dev,
10385 struct ieee80211_channel *chan,
10386 enum nl80211_channel_type channel_type
10387 )
10388{
10389 int ret;
10390
10391 vos_ssr_protect(__func__);
10392 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10393 vos_ssr_unprotect(__func__);
10394
10395 return ret;
10396}
10397
Anurag Chouhan83026002016-12-13 22:46:21 +053010398#ifdef DHCP_SERVER_OFFLOAD
10399void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10400 VOS_STATUS status)
10401{
10402 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10403
10404 ENTER();
10405
10406 if (NULL == adapter)
10407 {
10408 hddLog(VOS_TRACE_LEVEL_ERROR,
10409 "%s: adapter is NULL",__func__);
10410 return;
10411 }
10412
10413 adapter->dhcp_status.dhcp_offload_status = status;
10414 vos_event_set(&adapter->dhcp_status.vos_event);
10415 return;
10416}
10417
10418/**
10419 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10420 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010421 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010422 *
10423 * Return: None
10424 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010425VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10426 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010427{
10428 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10429 sir_dhcp_srv_offload_info dhcp_srv_info;
10430 tANI_U8 num_entries = 0;
10431 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10432 tANI_U8 num;
10433 tANI_U32 temp;
10434 VOS_STATUS ret;
10435
10436 ENTER();
10437
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010438 if (!re_init) {
10439 ret = wlan_hdd_validate_context(hdd_ctx);
10440 if (0 != ret)
10441 return VOS_STATUS_E_INVAL;
10442 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010443
10444 /* Prepare the request to send to SME */
10445 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10446 if (NULL == dhcp_srv_info) {
10447 hddLog(VOS_TRACE_LEVEL_ERROR,
10448 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10449 return VOS_STATUS_E_NOMEM;
10450 }
10451
10452 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10453
10454 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10455 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10456 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10457 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10458 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10459 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10460
10461 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10462 srv_ip,
10463 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010464 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010465 if (num_entries != IPADDR_NUM_ENTRIES) {
10466 hddLog(VOS_TRACE_LEVEL_ERROR,
10467 "%s: incorrect IP address (%s) assigned for DHCP server!",
10468 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10469 vos_mem_free(dhcp_srv_info);
10470 return VOS_STATUS_E_FAILURE;
10471 }
10472
10473 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10474 hddLog(VOS_TRACE_LEVEL_ERROR,
10475 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10476 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10477 vos_mem_free(dhcp_srv_info);
10478 return VOS_STATUS_E_FAILURE;
10479 }
10480
10481 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10482 hddLog(VOS_TRACE_LEVEL_ERROR,
10483 "%s: invalid IP address (%s)! The last field must be less than 100!",
10484 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10485 vos_mem_free(dhcp_srv_info);
10486 return VOS_STATUS_E_FAILURE;
10487 }
10488
10489 for (num = 0; num < num_entries; num++) {
10490 temp = srv_ip[num];
10491 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10492 }
10493
10494 if (eHAL_STATUS_SUCCESS !=
10495 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10496 hddLog(VOS_TRACE_LEVEL_ERROR,
10497 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10498 vos_mem_free(dhcp_srv_info);
10499 return VOS_STATUS_E_FAILURE;
10500 }
10501
10502 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10503 "%s: enable DHCP Server offload successfully!", __func__);
10504
10505 vos_mem_free(dhcp_srv_info);
10506 return 0;
10507}
10508#endif /* DHCP_SERVER_OFFLOAD */
10509
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010510/*
10511 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10512 * @wiphy_chan: wiphy channel number
10513 * @rfChannel: channel hw value
10514 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010515 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010516 *
10517 * Modify wiphy flags and cds state if channel is indoor.
10518 *
10519 * Return: void
10520 */
10521void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010522 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010523{
10524 v_U32_t channelLoop;
10525 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10526
10527 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10528
10529 if (rfChannels[channelLoop].channelNum == rfChannel) {
10530 channelEnum = (eRfChannels)channelLoop;
10531 break;
10532 }
10533 }
10534
10535 if (INVALID_RF_CHANNEL == channelEnum)
10536 return;
10537
10538 if (disable) {
10539 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10540 wiphy_chan->flags |=
10541 IEEE80211_CHAN_DISABLED;
10542 regChannels[channelEnum].enabled =
10543 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010544 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10545 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010546 }
10547 } else {
10548 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10549 wiphy_chan->flags &=
10550 ~IEEE80211_CHAN_DISABLED;
10551 /*
10552 * Indoor channels are marked as DFS
10553 * during regulatory processing
10554 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010555 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10556 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10557 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10558 && (wiphy_chan->flags &
10559 IEEE80211_CHAN_INDOOR_ONLY))) {
10560 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10561 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10562 channelEnum);
10563 } else {
10564 regChannels[channelEnum].enabled =
10565 NV_CHANNEL_ENABLE;
10566 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10567 channelEnum);
10568 }
10569 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010570
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010571 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010572}
10573
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010574void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010575{
10576 int band_num;
10577 int chan_num;
10578 v_U32_t rfChannel;
10579 struct ieee80211_channel *wiphy_chan;
10580 struct wiphy *wiphy;
10581
10582 ENTER();
10583 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10584
10585 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010586 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010587
10588 if (wiphy->bands[band_num] == NULL)
10589 continue;
10590
10591 for (chan_num = 0;
10592 chan_num < wiphy->bands[band_num]->n_channels;
10593 chan_num++) {
10594
10595 wiphy_chan =
10596 &(wiphy->bands[band_num]->channels[chan_num]);
10597 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10598
10599 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010600 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010601 }
10602 }
10603 EXIT();
10604}
10605
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010606int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10607{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010608 eHalStatus status;
10609 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010610 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10611 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10612 long ret;
10613 eConnectionState prev_conn_state;
10614 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10615
10616 ENTER();
10617
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010618 /* Indicate sme of disconnect so that in progress connection or preauth
10619 * can be aborted
10620 */
10621 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10622 pAdapter->sessionId);
10623 pHddCtx->isAmpAllowed = VOS_TRUE;
10624
10625 /* Need to apply spin lock before decreasing active sessions
10626 * as there can be chance for double decrement if context switch
10627 * Calls hdd_DisConnectHandler.
10628 */
10629
10630 prev_conn_state = pHddStaCtx->conn_info.connState;
10631
10632 spin_lock_bh(&pAdapter->lock_for_active_session);
10633 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10634 {
10635 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10636 }
10637 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10638 spin_unlock_bh(&pAdapter->lock_for_active_session);
10639 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10640
10641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10642 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10643
10644 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10645
10646 /*
10647 * stop tx queues before deleting STA/BSS context from the firmware.
10648 * tx has to be disabled because the firmware can get busy dropping
10649 * the tx frames after BSS/STA has been deleted and will not send
10650 * back a response resulting in WDI timeout
10651 */
10652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10653 netif_tx_disable(pAdapter->dev);
10654 netif_carrier_off(pAdapter->dev);
10655
10656 wlan_hdd_check_and_stop_mon(pAdapter, true);
10657
10658 /*issue disconnect*/
10659 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10660 pAdapter->sessionId, reason);
10661 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10662 prev_conn_state != eConnectionState_Connecting)
10663 {
10664 hddLog(LOG1,
10665 FL("status = %d, already disconnected"), status);
10666 result = 0;
10667 /*
10668 * Wait here instead of returning directly. This will block the
10669 * next connect command and allow processing of the disconnect
10670 * in SME else we might hit some race conditions leading to SME
10671 * and HDD out of sync. As disconnect is already in progress,
10672 * wait here for 1 sec instead of 5 sec.
10673 */
10674 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10675 goto wait_for_disconnect;
10676 }
10677 /*
10678 * Wait here instead of returning directly, this will block the next
10679 * connect command and allow processing of the scan for ssid and
10680 * the previous connect command in CSR. Else we might hit some
10681 * race conditions leading to SME and HDD out of sync.
10682 */
10683 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10684 {
10685 hddLog(LOG1,
10686 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10687 }
10688 else if ( 0 != status )
10689 {
10690 hddLog(LOGE,
10691 FL("csrRoamDisconnect failure, returned %d"),
10692 (int)status);
10693 result = -EINVAL;
10694 goto disconnected;
10695 }
10696wait_for_disconnect:
10697 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10698 msecs_to_jiffies(wait_time));
10699 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10700 {
10701 hddLog(LOGE,
10702 "%s: Failed to disconnect, timed out", __func__);
10703 result = -ETIMEDOUT;
10704 }
10705disconnected:
10706 hddLog(LOG1,
10707 FL("Set HDD connState to eConnectionState_NotConnected"));
10708 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10709#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10710 /* Sending disconnect event to userspace for kernel version < 3.11
10711 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10712 */
10713 hddLog(LOG1, FL("Send disconnected event to userspace"));
10714
10715 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10716 WLAN_REASON_UNSPECIFIED);
10717#endif
10718
10719 EXIT();
10720 return result;
10721}
10722
10723/*
10724 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10725 * on indoor channel
10726 * @hdd_ctx: pointer to hdd context
10727 *
10728 * STA should be disconnected before starting the SAP if it is on indoor
10729 * channel.
10730 *
10731 * Return: void
10732 */
10733void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10734{
10735
10736 hdd_adapter_t *sta_adapter;
10737 tANI_U8 sta_chan;
10738
10739 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10740
10741 if (!sta_chan) {
10742 hddLog(LOG1, FL("STA not connected"));
10743 return;
10744 }
10745
10746 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10747
10748 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10749 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10750 sta_chan);
10751 return;
10752 }
10753
10754 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10755
10756 if (!sta_adapter) {
10757 hddLog(LOG1, FL("STA adapter doesn't exist"));
10758 return;
10759 }
10760
10761 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10762 /* Issue Disconnect request */
10763 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10764}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010765
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010766int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10767{
10768 struct hdd_cache_channels *cache_chann;
10769 struct wiphy *wiphy;
10770 int freq, status, rfChannel;
10771 int i, band_num, channel_num;
10772 struct ieee80211_channel *wiphy_channel;
10773
10774 ENTER();
10775
10776 if (!hdd_ctx) {
10777 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10778 return -EINVAL;
10779 }
10780
10781 wiphy = hdd_ctx->wiphy;
10782
10783 mutex_lock(&hdd_ctx->cache_channel_lock);
10784
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010785 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010786
10787 if (!cache_chann || !cache_chann->num_channels) {
10788 hddLog(VOS_TRACE_LEVEL_INFO,
10789 "%s channel list is NULL or num channels are zero",
10790 __func__);
10791 mutex_unlock(&hdd_ctx->cache_channel_lock);
10792 return -EINVAL;
10793 }
10794
10795 for (i = 0; i < cache_chann->num_channels; i++) {
10796 status = hdd_wlan_get_freq(
10797 cache_chann->channel_info[i].channel_num,
10798 &freq);
10799
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010800 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10801 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010802 if (!wiphy->bands[band_num])
10803 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010804 for (channel_num = 0; channel_num <
10805 wiphy->bands[band_num]->n_channels;
10806 channel_num++) {
10807 wiphy_channel = &(wiphy->bands[band_num]->
10808 channels[channel_num]);
10809 if (wiphy_channel->center_freq == freq) {
10810 rfChannel = wiphy_channel->hw_value;
10811 /*
10812 *Restore the orginal states
10813 *of the channels
10814 */
10815 vos_nv_set_channel_state(
10816 rfChannel,
10817 cache_chann->
10818 channel_info[i].reg_status);
10819 wiphy_channel->flags =
10820 cache_chann->
10821 channel_info[i].wiphy_status;
10822 break;
10823 }
10824 }
10825 if (channel_num < wiphy->bands[band_num]->n_channels)
10826 break;
10827 }
10828 }
10829
10830 mutex_unlock(&hdd_ctx->cache_channel_lock);
10831
10832 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10833 if (status)
10834 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10835 EXIT();
10836
10837 return 0;
10838}
10839
10840/*
10841 * wlan_hdd_disable_channels() - Cache the the channels
10842 * and current state of the channels from the channel list
10843 * received in the command and disable the channels on the
10844 * wiphy and NV table.
10845 * @hdd_ctx: Pointer to hdd context
10846 *
10847 * @return: 0 on success, Error code on failure
10848 */
10849
10850static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10851{
10852 struct hdd_cache_channels *cache_chann;
10853 struct wiphy *wiphy;
10854 int freq, status, rfChannel;
10855 int i, band_num, band_ch_num;
10856 struct ieee80211_channel *wiphy_channel;
10857
10858 if (!hdd_ctx) {
10859 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10860 return -EINVAL;
10861 }
10862
10863 wiphy = hdd_ctx->wiphy;
10864
10865 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010866 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010867
10868 if (!cache_chann || !cache_chann->num_channels) {
10869 hddLog(VOS_TRACE_LEVEL_INFO,
10870 "%s channel list is NULL or num channels are zero",
10871 __func__);
10872 mutex_unlock(&hdd_ctx->cache_channel_lock);
10873 return -EINVAL;
10874 }
10875
10876 for (i = 0; i < cache_chann->num_channels; i++) {
10877 status = hdd_wlan_get_freq(
10878 cache_chann->channel_info[i].channel_num,
10879 &freq);
10880
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010881 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010882 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010883 if (!wiphy->bands[band_num])
10884 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010885 for (band_ch_num = 0; band_ch_num <
10886 wiphy->bands[band_num]->n_channels;
10887 band_ch_num++) {
10888 wiphy_channel = &(wiphy->bands[band_num]->
10889 channels[band_ch_num]);
10890 if (wiphy_channel->center_freq == freq) {
10891 rfChannel = wiphy_channel->hw_value;
10892 /*
10893 * Cache the current states of
10894 * the channels
10895 */
10896 cache_chann->
10897 channel_info[i].reg_status =
10898 vos_nv_getChannelEnabledState(
10899 rfChannel);
10900
10901 cache_chann->
10902 channel_info[i].wiphy_status =
10903 wiphy_channel->flags;
10904 hddLog(VOS_TRACE_LEVEL_INFO,
10905 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10906 cache_chann->
10907 channel_info[i].channel_num,
10908 cache_chann->
10909 channel_info[i].reg_status,
10910 wiphy_channel->flags);
10911
10912 vos_nv_set_channel_state(
10913 rfChannel,
10914 NV_CHANNEL_DISABLE);
10915 wiphy_channel->flags |=
10916 IEEE80211_CHAN_DISABLED;
10917 break;
10918 }
10919 }
10920 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10921 break;
10922 }
10923 }
10924
10925 mutex_unlock(&hdd_ctx->cache_channel_lock);
10926 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10927 return 0;
10928}
10929
Jeff Johnson295189b2012-06-20 16:38:30 -070010930#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10931static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10932 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010933#else
10934static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10935 struct cfg80211_beacon_data *params,
10936 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010937 enum nl80211_hidden_ssid hidden_ssid,
10938 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010940{
10941 tsap_Config_t *pConfig;
10942 beacon_data_t *pBeacon = NULL;
10943 struct ieee80211_mgmt *pMgmt_frame;
10944 v_U8_t *pIe=NULL;
10945 v_U16_t capab_info;
10946 eCsrAuthType RSNAuthType;
10947 eCsrEncryptionType RSNEncryptType;
10948 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010949 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 tpWLAN_SAPEventCB pSapEventCallback;
10951 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010953 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010955 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010956 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010957 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010958 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053010959 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010960 v_BOOL_t MFPCapable = VOS_FALSE;
10961 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010962 v_BOOL_t sapEnable11AC =
10963 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010964 u_int16_t prev_rsn_length = 0;
10965
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 ENTER();
10967
Nitesh Shah9b066282017-06-06 18:05:52 +053010968 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010969
10970 /*
10971 * For STA+SAP concurrency support from GUI, first STA connection gets
10972 * triggered and while it is in progress, SAP start also comes up.
10973 * Once STA association is successful, STA connect event is sent to
10974 * kernel which gets queued in kernel workqueue and supplicant won't
10975 * process M1 received from AP and send M2 until this NL80211_CONNECT
10976 * event is received. Workqueue is not scheduled as RTNL lock is already
10977 * taken by hostapd thread which has issued start_bss command to driver.
10978 * Driver cannot complete start_bss as the pending command at the head
10979 * of the SME command pending list is hw_mode_update for STA session
10980 * which cannot be processed as SME is in WAITforKey state for STA
10981 * interface. The start_bss command for SAP interface is queued behind
10982 * the hw_mode_update command and so it cannot be processed until
10983 * hw_mode_update command is processed. This is causing a deadlock so
10984 * disconnect the STA interface first if connection or key exchange is
10985 * in progress and then start SAP interface.
10986 */
10987 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
10988 if (sta_adapter) {
10989 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
10990 sta_adapter->sessionId);
10991 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10992 }
10993
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010994 iniConfig = pHddCtx->cfg_ini;
10995
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010996 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053010997 if (iniConfig->disable_indoor_channel &&
10998 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010999 hdd_update_indoor_channel(pHddCtx, true);
11000
11001 if (!VOS_IS_STATUS_SUCCESS(
11002 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11003 hdd_update_indoor_channel(pHddCtx, false);
11004 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11005 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011006 ret = eHAL_STATUS_FAILURE;
11007 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011008 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011009
11010 /* check if STA is on indoor channel */
11011 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11012 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011013 }
11014
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011015 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11016 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11017 wlan_hdd_disable_channels(pHddCtx);
11018 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11019 }
11020
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11022
11023 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11024
11025 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11026
11027 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11028
11029 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11030
11031 //channel is already set in the set_channel Call back
11032 //pConfig->channel = pCommitConfig->channel;
11033
11034 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011035 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11037
11038 pConfig->dtim_period = pBeacon->dtim_period;
11039
Arif Hussain6d2a3322013-11-17 19:50:10 -080011040 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 pConfig->dtim_period);
11042
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011043 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011044 {
11045 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011047 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11048 {
11049 tANI_BOOLEAN restartNeeded;
11050 pConfig->ieee80211d = 1;
11051 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11052 sme_setRegInfo(hHal, pConfig->countryCode);
11053 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11054 }
11055 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011057 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011058 pConfig->ieee80211d = 1;
11059 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11060 sme_setRegInfo(hHal, pConfig->countryCode);
11061 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011063 else
11064 {
11065 pConfig->ieee80211d = 0;
11066 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011067 /*
11068 * If auto channel is configured i.e. channel is 0,
11069 * so skip channel validation.
11070 */
11071 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11072 {
11073 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11074 {
11075 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011076 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011077 ret = -EINVAL;
11078 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011079 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011080 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011081 }
11082 else
11083 {
11084 if(1 != pHddCtx->is_dynamic_channel_range_set)
11085 {
11086 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11087 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11088 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11089 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011090 pHddCtx->is_dynamic_channel_range_set = 0;
11091 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011092 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011094 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 {
11096 pConfig->ieee80211d = 0;
11097 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011098
11099#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11100 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11101 pConfig->authType = eSAP_OPEN_SYSTEM;
11102 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11103 pConfig->authType = eSAP_SHARED_KEY;
11104 else
11105 pConfig->authType = eSAP_AUTO_SWITCH;
11106#else
11107 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11108 pConfig->authType = eSAP_OPEN_SYSTEM;
11109 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11110 pConfig->authType = eSAP_SHARED_KEY;
11111 else
11112 pConfig->authType = eSAP_AUTO_SWITCH;
11113#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011114
11115 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011116
11117 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011119#ifdef SAP_AUTH_OFFLOAD
11120 /* In case of sap offload, hostapd.conf is configuted with open mode and
11121 * security is configured from ini file. Due to open mode in hostapd.conf
11122 * privacy bit is set to false which will result in not sending,
11123 * data packets as encrypted.
11124 * If enable_sap_auth_offload is enabled in ini and
11125 * sap_auth_offload_sec_type is type of WPA2-PSK,
11126 * driver will set privacy bit to 1.
11127 */
11128 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11129 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11130 pConfig->privacy = VOS_TRUE;
11131#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011132
11133 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11134
11135 /*Set wps station to configured*/
11136 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11137
11138 if(pIe)
11139 {
11140 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11141 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011142 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011143 ret = -EINVAL;
11144 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 }
11146 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11147 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011148 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 /* Check 15 bit of WPS IE as it contain information for wps state
11150 * WPS state
11151 */
11152 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11153 {
11154 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11155 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11156 {
11157 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11158 }
11159 }
11160 }
11161 else
11162 {
11163 pConfig->wps_state = SAP_WPS_DISABLED;
11164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011165 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011166
c_hpothufe599e92014-06-16 11:38:55 +053011167 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11168 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11169 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11170 eCSR_ENCRYPT_TYPE_NONE;
11171
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011173 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011174 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011175 WLAN_EID_RSN);
11176 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011177 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011179 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11180 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11181 pConfig->RSNWPAReqIELength);
11182 else
11183 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11184 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011185 /* The actual processing may eventually be more extensive than
11186 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011187 * by the app.
11188 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11191 &RSNEncryptType,
11192 &mcRSNEncryptType,
11193 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011194 &MFPCapable,
11195 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011196 pConfig->RSNWPAReqIE[1]+2,
11197 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011198
11199 if( VOS_STATUS_SUCCESS == status )
11200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011201 /* Now copy over all the security attributes you have
11202 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011203 * */
11204 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11205 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11206 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11207 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011208 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011209 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011210 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11211 }
11212 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011213
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11215 pBeacon->tail, pBeacon->tail_len);
11216
11217 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11218 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011219 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 {
11221 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011222 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011224 if (pConfig->RSNWPAReqIELength <=
11225 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11226 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11227 pIe[1] + 2);
11228 else
11229 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11230 pConfig->RSNWPAReqIELength);
11231
Jeff Johnson295189b2012-06-20 16:38:30 -070011232 }
11233 else
11234 {
11235 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011236 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11237 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11238 pConfig->RSNWPAReqIELength);
11239 else
11240 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11241 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011242 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011243 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11244 &RSNEncryptType,
11245 &mcRSNEncryptType,
11246 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011247 &MFPCapable,
11248 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011249 pConfig->RSNWPAReqIE[1]+2,
11250 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011251
11252 if( VOS_STATUS_SUCCESS == status )
11253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011254 /* Now copy over all the security attributes you have
11255 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 * */
11257 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11258 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11259 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11260 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011261 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011262 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011263 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11264 }
11265 }
11266 }
11267
Kapil Gupta137ef892016-12-13 19:38:00 +053011268 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011269 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011270 ret = -EINVAL;
11271 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011272 }
11273
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11275
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011276#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 if (params->ssid != NULL)
11278 {
11279 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11280 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11281 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11282 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11283 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011284#else
11285 if (ssid != NULL)
11286 {
11287 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11288 pConfig->SSIDinfo.ssid.length = ssid_len;
11289 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11290 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11291 }
11292#endif
11293
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011294 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 /* default value */
11298 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11299 pConfig->num_accept_mac = 0;
11300 pConfig->num_deny_mac = 0;
11301
11302 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11303 pBeacon->tail, pBeacon->tail_len);
11304
11305 /* pIe for black list is following form:
11306 type : 1 byte
11307 length : 1 byte
11308 OUI : 4 bytes
11309 acl type : 1 byte
11310 no of mac addr in black list: 1 byte
11311 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011312 */
11313 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 {
11315 pConfig->SapMacaddr_acl = pIe[6];
11316 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011317 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011319 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11320 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11322 for (i = 0; i < pConfig->num_deny_mac; i++)
11323 {
11324 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11325 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011326 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 }
11328 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11329 pBeacon->tail, pBeacon->tail_len);
11330
11331 /* pIe for white list is following form:
11332 type : 1 byte
11333 length : 1 byte
11334 OUI : 4 bytes
11335 acl type : 1 byte
11336 no of mac addr in white list: 1 byte
11337 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011338 */
11339 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 {
11341 pConfig->SapMacaddr_acl = pIe[6];
11342 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011343 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011345 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11346 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11348 for (i = 0; i < pConfig->num_accept_mac; i++)
11349 {
11350 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11351 acl_entry++;
11352 }
11353 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011354
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11356
Jeff Johnsone7245742012-09-05 17:12:55 -070011357#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011358 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011359 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11360 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011361 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11362 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011363 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11364 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011365 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11366 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011367 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011368 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011369 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011370 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011371
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011372 /* If ACS disable and selected channel <= 14
11373 * OR
11374 * ACS enabled and ACS operating band is choosen as 2.4
11375 * AND
11376 * VHT in 2.4G Disabled
11377 * THEN
11378 * Fallback to 11N mode
11379 */
11380 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11381 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011382 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011383 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011384 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011385 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11386 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011387 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11388 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011389 }
11390#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011391
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 // ht_capab is not what the name conveys,this is used for protection bitmap
11393 pConfig->ht_capab =
11394 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11395
Kapil Gupta137ef892016-12-13 19:38:00 +053011396 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 {
11398 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011399 ret = -EINVAL;
11400 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011401 }
11402
11403 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011404 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11406 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011407 pConfig->obssProtEnabled =
11408 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011409
Chet Lanctot8cecea22014-02-11 19:09:36 -080011410#ifdef WLAN_FEATURE_11W
11411 pConfig->mfpCapable = MFPCapable;
11412 pConfig->mfpRequired = MFPRequired;
11413 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11414 pConfig->mfpCapable, pConfig->mfpRequired);
11415#endif
11416
Arif Hussain6d2a3322013-11-17 19:50:10 -080011417 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011419 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11420 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11421 (int)pConfig->channel);
11422 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11423 pConfig->SapHw_mode, pConfig->privacy,
11424 pConfig->authType);
11425 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11426 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11427 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11428 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011429
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011430 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 {
11432 //Bss already started. just return.
11433 //TODO Probably it should update some beacon params.
11434 hddLog( LOGE, "Bss Already started...Ignore the request");
11435 EXIT();
11436 return 0;
11437 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011438
Agarwal Ashish51325b52014-06-16 16:50:49 +053011439 if (vos_max_concurrent_connections_reached()) {
11440 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011441 ret = -EINVAL;
11442 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011443 }
11444
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 pConfig->persona = pHostapdAdapter->device_mode;
11446
Peng Xu2446a892014-09-05 17:21:18 +053011447 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11448 if ( NULL != psmeConfig)
11449 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011450 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011451 sme_GetConfigParam(hHal, psmeConfig);
11452 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011453#ifdef WLAN_FEATURE_AP_HT40_24G
11454 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11455 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11456 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11457 {
11458 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11459 sme_UpdateConfig (hHal, psmeConfig);
11460 }
11461#endif
Peng Xu2446a892014-09-05 17:21:18 +053011462 vos_mem_free(psmeConfig);
11463 }
Peng Xuafc34e32014-09-25 13:23:55 +053011464 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011465
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011466 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011468
11469 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11471 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11472 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011473 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011474 ret = -EINVAL;
11475 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 }
11477
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011478 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11480
11481 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011482
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484 {
11485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011486 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011487 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011488 VOS_ASSERT(0);
11489 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011492 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11493 VOS_STATUS_SUCCESS)
11494 {
11495 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11496 VOS_ASSERT(0);
11497 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011498 /* Initialize WMM configuation */
11499 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011500 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011501
Anurag Chouhan83026002016-12-13 22:46:21 +053011502#ifdef DHCP_SERVER_OFFLOAD
11503 /* set dhcp server offload */
11504 if (iniConfig->enable_dhcp_srv_offload &&
11505 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011506 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011507 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011508 if (!VOS_IS_STATUS_SUCCESS(status))
11509 {
11510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11511 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011512 vos_event_reset(&pHostapdState->vosEvent);
11513 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11514 status = vos_wait_single_event(&pHostapdState->vosEvent,
11515 10000);
11516 if (!VOS_IS_STATUS_SUCCESS(status)) {
11517 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011518 ret = -EINVAL;
11519 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011520 }
11521 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011522 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011523 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11524 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11525 {
11526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11527 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11528 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011529 vos_event_reset(&pHostapdState->vosEvent);
11530 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11531 status = vos_wait_single_event(&pHostapdState->vosEvent,
11532 10000);
11533 if (!VOS_IS_STATUS_SUCCESS(status)) {
11534 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011535 ret = -EINVAL;
11536 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011537 }
11538 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011539 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011540#ifdef MDNS_OFFLOAD
11541 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011542 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011543 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11544 if (VOS_IS_STATUS_SUCCESS(status))
11545 {
11546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11547 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011548 vos_event_reset(&pHostapdState->vosEvent);
11549 if (VOS_STATUS_SUCCESS ==
11550 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11551 status = vos_wait_single_event(&pHostapdState->vosEvent,
11552 10000);
11553 if (!VOS_IS_STATUS_SUCCESS(status)) {
11554 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011555 ret = -EINVAL;
11556 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011557 }
11558 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011559 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011560 status = vos_wait_single_event(&pHostapdAdapter->
11561 mdns_status.vos_event, 2000);
11562 if (!VOS_IS_STATUS_SUCCESS(status) ||
11563 pHostapdAdapter->mdns_status.mdns_enable_status ||
11564 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11565 pHostapdAdapter->mdns_status.mdns_resp_status)
11566 {
11567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11568 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11569 pHostapdAdapter->mdns_status.mdns_enable_status,
11570 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11571 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011572 vos_event_reset(&pHostapdState->vosEvent);
11573 if (VOS_STATUS_SUCCESS ==
11574 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11575 status = vos_wait_single_event(&pHostapdState->vosEvent,
11576 10000);
11577 if (!VOS_IS_STATUS_SUCCESS(status)) {
11578 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011579 ret = -EINVAL;
11580 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011581 }
11582 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011583 }
11584 }
11585#endif /* MDNS_OFFLOAD */
11586 } else {
11587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11588 ("DHCP Disabled ini %d, FW %d"),
11589 iniConfig->enable_dhcp_srv_offload,
11590 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011591 }
11592#endif /* DHCP_SERVER_OFFLOAD */
11593
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011594#ifdef WLAN_FEATURE_P2P_DEBUG
11595 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11596 {
11597 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11598 {
11599 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11600 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011601 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011602 }
11603 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11604 {
11605 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11606 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011607 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011608 }
11609 }
11610#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011611 /* Check and restart SAP if it is on Unsafe channel */
11612 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011613
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 pHostapdState->bCommit = TRUE;
11615 EXIT();
11616
11617 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011618error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011619 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11620 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011621 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011622 if (iniConfig->disable_indoor_channel &&
11623 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011624 hdd_update_indoor_channel(pHddCtx, false);
11625 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11626 }
11627
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011628 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011629
11630tdls_enable:
11631 if (ret != eHAL_STATUS_SUCCESS)
11632 wlan_hdd_tdls_reenable(pHddCtx);
11633
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011634 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011635}
11636
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011637#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011638static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011639 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011640 struct beacon_parameters *params)
11641{
11642 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011643 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011644 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011645
11646 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011647
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011648 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11649 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11650 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011651 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11652 hdd_device_modetoString(pAdapter->device_mode),
11653 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011654
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011655 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11656 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011657 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011658 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011659 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011660 }
11661
Agarwal Ashish51325b52014-06-16 16:50:49 +053011662 if (vos_max_concurrent_connections_reached()) {
11663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11664 return -EINVAL;
11665 }
11666
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011667 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 )
11670 {
11671 beacon_data_t *old,*new;
11672
11673 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011676 {
11677 hddLog(VOS_TRACE_LEVEL_WARN,
11678 FL("already beacon info added to session(%d)"),
11679 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011681 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011682
11683 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11684
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011685 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 {
11687 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011688 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 return -EINVAL;
11690 }
11691
11692 pAdapter->sessionCtx.ap.beacon = new;
11693
11694 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11695 }
11696
11697 EXIT();
11698 return status;
11699}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011701static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11702 struct net_device *dev,
11703 struct beacon_parameters *params)
11704{
11705 int ret;
11706
11707 vos_ssr_protect(__func__);
11708 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11709 vos_ssr_unprotect(__func__);
11710
11711 return ret;
11712}
11713
11714static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 struct net_device *dev,
11716 struct beacon_parameters *params)
11717{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011719 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11720 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011721 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011722
11723 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011724
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11726 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11727 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11729 __func__, hdd_device_modetoString(pAdapter->device_mode),
11730 pAdapter->device_mode);
11731
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11733 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011734 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011735 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011736 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011737 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011738
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011741 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 {
11743 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011746
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011748 {
11749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11750 FL("session(%d) old and new heads points to NULL"),
11751 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011753 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011754
11755 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11756
11757 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011759 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 return -EINVAL;
11761 }
11762
11763 pAdapter->sessionCtx.ap.beacon = new;
11764
11765 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11766 }
11767
11768 EXIT();
11769 return status;
11770}
11771
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011772static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11773 struct net_device *dev,
11774 struct beacon_parameters *params)
11775{
11776 int ret;
11777
11778 vos_ssr_protect(__func__);
11779 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11780 vos_ssr_unprotect(__func__);
11781
11782 return ret;
11783}
11784
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011785#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11786
11787#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011788static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011790#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011791static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011792 struct net_device *dev)
11793#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011794{
11795 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011796 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011797 hdd_context_t *pHddCtx = NULL;
11798 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011799 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011800 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011801
11802 ENTER();
11803
11804 if (NULL == pAdapter)
11805 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011807 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 return -ENODEV;
11809 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011810
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11812 TRACE_CODE_HDD_CFG80211_STOP_AP,
11813 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011814 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11815 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011816 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011818 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011819 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011820
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011821 pScanInfo = &pHddCtx->scan_info;
11822
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11824 __func__, hdd_device_modetoString(pAdapter->device_mode),
11825 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011826
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011827 /*
11828 * if a sta connection is in progress in another adapter, disconnect
11829 * the sta and complete the sap operation. sta will reconnect
11830 * after sap stop is done.
11831 */
11832 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11833 if (staAdapter) {
11834 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11835 staAdapter->sessionId);
11836 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11837 }
11838
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011839 ret = wlan_hdd_scan_abort(pAdapter);
11840
Girish Gowli4bf7a632014-06-12 13:42:11 +053011841 if (ret < 0)
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 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011845
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011846 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011847 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11849 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011850
Jeff Johnsone7245742012-09-05 17:12:55 -070011851 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011852 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011853 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011854 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011855 }
11856
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011857 /* Delete all associated STAs before stopping AP/P2P GO */
11858 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011859 hdd_hostapd_stop(dev);
11860
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 )
11864 {
11865 beacon_data_t *old;
11866
11867 old = pAdapter->sessionCtx.ap.beacon;
11868
11869 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011870 {
11871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11872 FL("session(%d) beacon data points to NULL"),
11873 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011875 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011876
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011878
11879 mutex_lock(&pHddCtx->sap_lock);
11880 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11881 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011882 hdd_hostapd_state_t *pHostapdState =
11883 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11884
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011885 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11886 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011887 vos_event_reset(&pHostapdState->vosEvent);
11888
Jeff Johnson4416a782013-03-25 14:17:50 -070011889 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011890 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11892
11893 if (!VOS_IS_STATUS_SUCCESS(status))
11894 {
11895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011896 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011898 }
11899 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011901 /* BSS stopped, clear the active sessions for this device mode */
11902 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 }
11904 mutex_unlock(&pHddCtx->sap_lock);
11905
11906 if(status != VOS_STATUS_SUCCESS)
11907 {
11908 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011909 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 return -EINVAL;
11911 }
11912
Jeff Johnson4416a782013-03-25 14:17:50 -070011913 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11915 ==eHAL_STATUS_FAILURE)
11916 {
11917 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011918 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 }
11920
Jeff Johnson4416a782013-03-25 14:17:50 -070011921 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11923 eANI_BOOLEAN_FALSE) )
11924 {
11925 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011926 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 }
11928
11929 // Reset WNI_CFG_PROBE_RSP Flags
11930 wlan_hdd_reset_prob_rspies(pAdapter);
11931
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011932 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11933
Jeff Johnson295189b2012-06-20 16:38:30 -070011934 pAdapter->sessionCtx.ap.beacon = NULL;
11935 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011936#ifdef WLAN_FEATURE_P2P_DEBUG
11937 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11938 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11939 {
11940 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11941 "GO got removed");
11942 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11943 }
11944#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 }
11946 EXIT();
11947 return status;
11948}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011949
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011950#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11951static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11952 struct net_device *dev)
11953{
11954 int ret;
11955
11956 vos_ssr_protect(__func__);
11957 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11958 vos_ssr_unprotect(__func__);
11959
11960 return ret;
11961}
11962#else
11963static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11964 struct net_device *dev)
11965{
11966 int ret;
11967
11968 vos_ssr_protect(__func__);
11969 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11970 vos_ssr_unprotect(__func__);
11971
11972 return ret;
11973}
11974#endif
11975
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011976#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11977
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011978static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011979 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011980 struct cfg80211_ap_settings *params)
11981{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011982 hdd_adapter_t *pAdapter;
11983 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011984 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011985
11986 ENTER();
11987
Girish Gowlib143d7a2015-02-18 19:39:55 +053011988 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011989 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011991 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011992 return -ENODEV;
11993 }
11994
11995 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11996 if (NULL == pAdapter)
11997 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011999 "%s: HDD adapter is Null", __func__);
12000 return -ENODEV;
12001 }
12002
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012003 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12004 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12005 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012006 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012009 "%s: HDD adapter magic is invalid", __func__);
12010 return -ENODEV;
12011 }
12012
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012013 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12014
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012015 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012016 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012017 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012018 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012019 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012020 }
12021
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012022 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12023 __func__, hdd_device_modetoString(pAdapter->device_mode),
12024 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012025
12026 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012027 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012028 )
12029 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012030 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012031
12032 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012033
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012035 {
12036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12037 FL("already beacon info added to session(%d)"),
12038 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012039 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012040 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012041
Girish Gowlib143d7a2015-02-18 19:39:55 +053012042#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12043 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12044 &new,
12045 &params->beacon);
12046#else
12047 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12048 &new,
12049 &params->beacon,
12050 params->dtim_period);
12051#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012052
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012053 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012054 {
12055 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012056 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012057 return -EINVAL;
12058 }
12059 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012060#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012061 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12062#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12063 params->channel, params->channel_type);
12064#else
12065 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12066#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012067#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012068 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012069 params->ssid_len, params->hidden_ssid,
12070 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012071 }
12072
12073 EXIT();
12074 return status;
12075}
12076
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012077static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12078 struct net_device *dev,
12079 struct cfg80211_ap_settings *params)
12080{
12081 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012082
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012083 vos_ssr_protect(__func__);
12084 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12085 vos_ssr_unprotect(__func__);
12086
12087 return ret;
12088}
12089
12090static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012091 struct net_device *dev,
12092 struct cfg80211_beacon_data *params)
12093{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012095 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012096 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012097
12098 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012099
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012100 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12101 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12102 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012104 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012105
12106 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12107 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012108 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012109 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012110 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012111 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012112
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012114 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 {
12117 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012118
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012119 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012120
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012121 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012122 {
12123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12124 FL("session(%d) beacon data points to NULL"),
12125 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012126 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012127 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012128
12129 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12130
12131 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012132 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012133 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012134 return -EINVAL;
12135 }
12136
12137 pAdapter->sessionCtx.ap.beacon = new;
12138
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012139 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12140 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012141 }
12142
12143 EXIT();
12144 return status;
12145}
12146
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012147static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12148 struct net_device *dev,
12149 struct cfg80211_beacon_data *params)
12150{
12151 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012152
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012153 vos_ssr_protect(__func__);
12154 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12155 vos_ssr_unprotect(__func__);
12156
12157 return ret;
12158}
12159
12160#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012161
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012162static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 struct net_device *dev,
12164 struct bss_parameters *params)
12165{
12166 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012167 hdd_context_t *pHddCtx;
12168 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012169
12170 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012171
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012172 if (NULL == pAdapter)
12173 {
12174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12175 "%s: HDD adapter is Null", __func__);
12176 return -ENODEV;
12177 }
12178 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012179 ret = wlan_hdd_validate_context(pHddCtx);
12180 if (0 != ret)
12181 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012182 return ret;
12183 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012184 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12185 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12186 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12188 __func__, hdd_device_modetoString(pAdapter->device_mode),
12189 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012190
12191 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012193 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 {
12195 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12196 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012197 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 {
12199 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012200 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 }
12202
12203 EXIT();
12204 return 0;
12205}
12206
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012207static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12208 struct net_device *dev,
12209 struct bss_parameters *params)
12210{
12211 int ret;
12212
12213 vos_ssr_protect(__func__);
12214 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12215 vos_ssr_unprotect(__func__);
12216
12217 return ret;
12218}
Kiet Lam10841362013-11-01 11:36:50 +053012219/* FUNCTION: wlan_hdd_change_country_code_cd
12220* to wait for contry code completion
12221*/
12222void* wlan_hdd_change_country_code_cb(void *pAdapter)
12223{
12224 hdd_adapter_t *call_back_pAdapter = pAdapter;
12225 complete(&call_back_pAdapter->change_country_code);
12226 return NULL;
12227}
12228
Jeff Johnson295189b2012-06-20 16:38:30 -070012229/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012230 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12232 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012233int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 struct net_device *ndev,
12235 enum nl80211_iftype type,
12236 u32 *flags,
12237 struct vif_params *params
12238 )
12239{
12240 struct wireless_dev *wdev;
12241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012242 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012244 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012245 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012246 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012247 eMib_dot11DesiredBssType connectedBssType;
12248 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012249 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012250
12251 ENTER();
12252
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012253 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012254 {
12255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12256 "%s: Adapter context is null", __func__);
12257 return VOS_STATUS_E_FAILURE;
12258 }
12259
12260 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12261 if (!pHddCtx)
12262 {
12263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12264 "%s: HDD context is null", __func__);
12265 return VOS_STATUS_E_FAILURE;
12266 }
12267
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012268 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12269 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12270 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012271 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012272 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012274 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 }
12276
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012277 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12278 __func__, hdd_device_modetoString(pAdapter->device_mode),
12279 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012280
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012281 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12282 hddLog(VOS_TRACE_LEVEL_FATAL,
12283 "%s: STA + MON is in progress, cannot change interface",
12284 __func__);
12285 }
12286
Agarwal Ashish51325b52014-06-16 16:50:49 +053012287 if (vos_max_concurrent_connections_reached()) {
12288 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12289 return -EINVAL;
12290 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012291 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012292 wdev = ndev->ieee80211_ptr;
12293
12294#ifdef WLAN_BTAMP_FEATURE
12295 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12296 (NL80211_IFTYPE_ADHOC == type)||
12297 (NL80211_IFTYPE_AP == type)||
12298 (NL80211_IFTYPE_P2P_GO == type))
12299 {
12300 pHddCtx->isAmpAllowed = VOS_FALSE;
12301 // stop AMP traffic
12302 status = WLANBAP_StopAmp();
12303 if(VOS_STATUS_SUCCESS != status )
12304 {
12305 pHddCtx->isAmpAllowed = VOS_TRUE;
12306 hddLog(VOS_TRACE_LEVEL_FATAL,
12307 "%s: Failed to stop AMP", __func__);
12308 return -EINVAL;
12309 }
12310 }
12311#endif //WLAN_BTAMP_FEATURE
12312 /* Reset the current device mode bit mask*/
12313 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12314
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012315 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12316 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12317 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012318 {
12319 /* Notify Mode change in case of concurrency.
12320 * Below function invokes TDLS teardown Functionality Since TDLS is
12321 * not Supported in case of concurrency i.e Once P2P session
12322 * is detected disable offchannel and teardown TDLS links
12323 */
12324 hddLog(LOG1,
12325 FL("Device mode = %d Interface type = %d"),
12326 pAdapter->device_mode, type);
12327 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12328 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012329
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012332 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 )
12334 {
12335 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012336 if (!pWextState)
12337 {
12338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12339 "%s: pWextState is null", __func__);
12340 return VOS_STATUS_E_FAILURE;
12341 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 pRoamProfile = &pWextState->roamProfile;
12343 LastBSSType = pRoamProfile->BSSType;
12344
12345 switch (type)
12346 {
12347 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012349 hddLog(VOS_TRACE_LEVEL_INFO,
12350 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12351 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012352#ifdef WLAN_FEATURE_11AC
12353 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12354 {
12355 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12356 }
12357#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012358 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012359 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012360 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012361 //Check for sub-string p2p to confirm its a p2p interface
12362 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012363 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012364#ifdef FEATURE_WLAN_TDLS
12365 mutex_lock(&pHddCtx->tdls_lock);
12366 wlan_hdd_tdls_exit(pAdapter, TRUE);
12367 mutex_unlock(&pHddCtx->tdls_lock);
12368#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012369 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12370 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12371 }
12372 else
12373 {
12374 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012376 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012378
Jeff Johnson295189b2012-06-20 16:38:30 -070012379 case NL80211_IFTYPE_ADHOC:
12380 hddLog(VOS_TRACE_LEVEL_INFO,
12381 "%s: setting interface Type to ADHOC", __func__);
12382 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12383 pRoamProfile->phyMode =
12384 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012385 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012387 hdd_set_ibss_ops( pAdapter );
12388 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012389
12390 status = hdd_sta_id_hash_attach(pAdapter);
12391 if (VOS_STATUS_SUCCESS != status) {
12392 hddLog(VOS_TRACE_LEVEL_ERROR,
12393 FL("Failed to initialize hash for IBSS"));
12394 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 break;
12396
12397 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 {
12400 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12401 "%s: setting interface Type to %s", __func__,
12402 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12403
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012404 //Cancel any remain on channel for GO mode
12405 if (NL80211_IFTYPE_P2P_GO == type)
12406 {
12407 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12408 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012409 if (NL80211_IFTYPE_AP == type)
12410 {
12411 /*
12412 * As Loading WLAN Driver one interface being created
12413 * for p2p device address. This will take one HW STA and
12414 * the max number of clients that can connect to softAP
12415 * will be reduced by one. so while changing the interface
12416 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12417 * as it is not required in SoftAP mode.
12418 */
12419
12420 // Get P2P Adapter
12421 pP2pAdapter = hdd_get_adapter(pHddCtx,
12422 WLAN_HDD_P2P_DEVICE);
12423 if (pP2pAdapter)
12424 {
Min Liuf3481952018-12-10 16:01:14 +080012425 wlan_hdd_release_intf_addr(pHddCtx,
12426 pP2pAdapter->macAddressCurrent.bytes);
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012427 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12428 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12429 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12430 }
12431 }
12432
Swaroop Goltia2e32212014-04-09 23:37:33 +053012433 //Disable IMPS & BMPS for SAP/GO
12434 if(VOS_STATUS_E_FAILURE ==
12435 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12436 {
12437 //Fail to Exit BMPS
12438 VOS_ASSERT(0);
12439 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012440
12441 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12442
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012443#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012444
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012445 /* A Mutex Lock is introduced while changing the mode to
12446 * protect the concurrent access for the Adapters by TDLS
12447 * module.
12448 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012449 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012450#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012451 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012452 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012453 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12455 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012456#ifdef FEATURE_WLAN_TDLS
12457 mutex_unlock(&pHddCtx->tdls_lock);
12458#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012459 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12460 (pConfig->apRandomBssidEnabled))
12461 {
12462 /* To meet Android requirements create a randomized
12463 MAC address of the form 02:1A:11:Fx:xx:xx */
12464 get_random_bytes(&ndev->dev_addr[3], 3);
12465 ndev->dev_addr[0] = 0x02;
12466 ndev->dev_addr[1] = 0x1A;
12467 ndev->dev_addr[2] = 0x11;
12468 ndev->dev_addr[3] |= 0xF0;
12469 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12470 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012471 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12472 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012473 }
12474
Jeff Johnson295189b2012-06-20 16:38:30 -070012475 hdd_set_ap_ops( pAdapter->dev );
12476
Kiet Lam10841362013-11-01 11:36:50 +053012477 /* This is for only SAP mode where users can
12478 * control country through ini.
12479 * P2P GO follows station country code
12480 * acquired during the STA scanning. */
12481 if((NL80211_IFTYPE_AP == type) &&
12482 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12483 {
12484 int status = 0;
12485 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12486 "%s: setting country code from INI ", __func__);
12487 init_completion(&pAdapter->change_country_code);
12488 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12489 (void *)(tSmeChangeCountryCallback)
12490 wlan_hdd_change_country_code_cb,
12491 pConfig->apCntryCode, pAdapter,
12492 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012493 eSIR_FALSE,
12494 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012495 if (eHAL_STATUS_SUCCESS == status)
12496 {
12497 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012498 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012499 &pAdapter->change_country_code,
12500 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012501 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012502 {
12503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012504 FL("SME Timed out while setting country code %ld"),
12505 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012506
12507 if (pHddCtx->isLogpInProgress)
12508 {
12509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12510 "%s: LOGP in Progress. Ignore!!!", __func__);
12511 return -EAGAIN;
12512 }
Kiet Lam10841362013-11-01 11:36:50 +053012513 }
12514 }
12515 else
12516 {
12517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012518 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012519 return -EINVAL;
12520 }
12521 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012522 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 if(status != VOS_STATUS_SUCCESS)
12524 {
12525 hddLog(VOS_TRACE_LEVEL_FATAL,
12526 "%s: Error initializing the ap mode", __func__);
12527 return -EINVAL;
12528 }
12529 hdd_set_conparam(1);
12530
Nirav Shah7e3c8132015-06-22 23:51:42 +053012531 status = hdd_sta_id_hash_attach(pAdapter);
12532 if (VOS_STATUS_SUCCESS != status)
12533 {
12534 hddLog(VOS_TRACE_LEVEL_ERROR,
12535 FL("Failed to initialize hash for AP"));
12536 return -EINVAL;
12537 }
12538
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 /*interface type changed update in wiphy structure*/
12540 if(wdev)
12541 {
12542 wdev->iftype = type;
12543 pHddCtx->change_iface = type;
12544 }
12545 else
12546 {
12547 hddLog(VOS_TRACE_LEVEL_ERROR,
12548 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12549 return -EINVAL;
12550 }
12551 goto done;
12552 }
12553
12554 default:
12555 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12556 __func__);
12557 return -EOPNOTSUPP;
12558 }
12559 }
12560 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 )
12563 {
12564 switch(type)
12565 {
12566 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012568 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012569
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012570 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12571 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12572 /*
12573 * The p2p interface was deleted while SoftAP mode was init,
12574 * create that interface now that the SoftAP is going down.
12575 */
12576 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12577 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12578 VOS_TRUE);
12579 }
12580
Deepthi Gowri500fc472014-08-11 19:53:10 +053012581 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012582
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012583#ifdef FEATURE_WLAN_TDLS
12584
12585 /* A Mutex Lock is introduced while changing the mode to
12586 * protect the concurrent access for the Adapters by TDLS
12587 * module.
12588 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012589 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012590#endif
c_hpothu002231a2015-02-05 14:58:51 +053012591 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012593 //Check for sub-string p2p to confirm its a p2p interface
12594 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012595 {
12596 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12597 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12598 }
12599 else
12600 {
12601 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012603 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012604
12605 /* set con_mode to STA only when no SAP concurrency mode */
12606 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12607 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12610 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012611#ifdef FEATURE_WLAN_TDLS
12612 mutex_unlock(&pHddCtx->tdls_lock);
12613#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012614 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012615 if( VOS_STATUS_SUCCESS != status )
12616 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012617 /* In case of JB, for P2P-GO, only change interface will be called,
12618 * This is the right place to enable back bmps_imps()
12619 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012620 if (pHddCtx->hdd_wlan_suspended)
12621 {
12622 hdd_set_pwrparams(pHddCtx);
12623 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012624 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 goto done;
12626 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012628 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12630 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 goto done;
12632 default:
12633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12634 __func__);
12635 return -EOPNOTSUPP;
12636
12637 }
12638
12639 }
12640 else
12641 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012642 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12643 __func__, hdd_device_modetoString(pAdapter->device_mode),
12644 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 return -EOPNOTSUPP;
12646 }
12647
12648
12649 if(pRoamProfile)
12650 {
12651 if ( LastBSSType != pRoamProfile->BSSType )
12652 {
12653 /*interface type changed update in wiphy structure*/
12654 wdev->iftype = type;
12655
12656 /*the BSS mode changed, We need to issue disconnect
12657 if connected or in IBSS disconnect state*/
12658 if ( hdd_connGetConnectedBssType(
12659 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12660 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12661 {
12662 /*need to issue a disconnect to CSR.*/
12663 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12664 if( eHAL_STATUS_SUCCESS ==
12665 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12666 pAdapter->sessionId,
12667 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12668 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012669 ret = wait_for_completion_interruptible_timeout(
12670 &pAdapter->disconnect_comp_var,
12671 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12672 if (ret <= 0)
12673 {
12674 hddLog(VOS_TRACE_LEVEL_ERROR,
12675 FL("wait on disconnect_comp_var failed %ld"), ret);
12676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 }
12678 }
12679 }
12680 }
12681
12682done:
12683 /*set bitmask based on updated value*/
12684 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012685
12686 /* Only STA mode support TM now
12687 * all other mode, TM feature should be disabled */
12688 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12689 (~VOS_STA & pHddCtx->concurrency_mode) )
12690 {
12691 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12692 }
12693
Jeff Johnson295189b2012-06-20 16:38:30 -070012694#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012695 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012696 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012697 {
12698 //we are ok to do AMP
12699 pHddCtx->isAmpAllowed = VOS_TRUE;
12700 }
12701#endif //WLAN_BTAMP_FEATURE
12702 EXIT();
12703 return 0;
12704}
12705
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012706/*
12707 * FUNCTION: wlan_hdd_cfg80211_change_iface
12708 * wrapper function to protect the actual implementation from SSR.
12709 */
12710int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12711 struct net_device *ndev,
12712 enum nl80211_iftype type,
12713 u32 *flags,
12714 struct vif_params *params
12715 )
12716{
12717 int ret;
12718
12719 vos_ssr_protect(__func__);
12720 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12721 vos_ssr_unprotect(__func__);
12722
12723 return ret;
12724}
12725
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012726#ifdef FEATURE_WLAN_TDLS
12727static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012728 struct net_device *dev,
12729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12730 const u8 *mac,
12731#else
12732 u8 *mac,
12733#endif
12734 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012735{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012736 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012737 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012738 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012739 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012740 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012741 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012742
12743 ENTER();
12744
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012745 if (!dev) {
12746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12747 return -EINVAL;
12748 }
12749
12750 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12751 if (!pAdapter) {
12752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12753 return -EINVAL;
12754 }
12755
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012756 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012757 {
12758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12759 "Invalid arguments");
12760 return -EINVAL;
12761 }
Hoonki Lee27511902013-03-14 18:19:06 -070012762
12763 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12764 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12765 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012767 "%s: TDLS mode is disabled OR not enabled in FW."
12768 MAC_ADDRESS_STR " Request declined.",
12769 __func__, MAC_ADDR_ARRAY(mac));
12770 return -ENOTSUPP;
12771 }
12772
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012773 if (pHddCtx->isLogpInProgress)
12774 {
12775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12776 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012777 wlan_hdd_tdls_set_link_status(pAdapter,
12778 mac,
12779 eTDLS_LINK_IDLE,
12780 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012781 return -EBUSY;
12782 }
12783
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012784 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012785 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012786
12787 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012789 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12790 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012791 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012792 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012793 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012794
12795 /* in add station, we accept existing valid staId if there is */
12796 if ((0 == update) &&
12797 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12798 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012799 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012801 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012802 " link_status %d. staId %d. add station ignored.",
12803 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012804 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012805 return 0;
12806 }
12807 /* in change station, we accept only when staId is valid */
12808 if ((1 == update) &&
12809 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12810 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12811 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012812 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012814 "%s: " MAC_ADDRESS_STR
12815 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012816 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12817 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12818 mutex_unlock(&pHddCtx->tdls_lock);
12819 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012820 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012821 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012822
12823 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012824 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012825 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12827 "%s: " MAC_ADDRESS_STR
12828 " TDLS setup is ongoing. Request declined.",
12829 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012830 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012831 }
12832
12833 /* first to check if we reached to maximum supported TDLS peer.
12834 TODO: for now, return -EPERM looks working fine,
12835 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012836 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12837 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012838 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12840 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012841 " TDLS Max peer already connected. Request declined."
12842 " Num of peers (%d), Max allowed (%d).",
12843 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12844 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012845 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012846 }
12847 else
12848 {
12849 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012850 mutex_lock(&pHddCtx->tdls_lock);
12851 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012852 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012853 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012854 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12856 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12857 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012858 return -EPERM;
12859 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012860 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012861 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012862 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012863 wlan_hdd_tdls_set_link_status(pAdapter,
12864 mac,
12865 eTDLS_LINK_CONNECTING,
12866 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012867
Jeff Johnsond75fe012013-04-06 10:53:06 -070012868 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012869 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012870 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012872 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012873 if(StaParams->htcap_present)
12874 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012876 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012878 "ht_capa->extended_capabilities: %0x",
12879 StaParams->HTCap.extendedHtCapInfo);
12880 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012882 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012884 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012885 if(StaParams->vhtcap_present)
12886 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012888 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12889 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12890 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12891 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012892 {
12893 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012895 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012897 "[%d]: %x ", i, StaParams->supported_rates[i]);
12898 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012899 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012900 else if ((1 == update) && (NULL == StaParams))
12901 {
12902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12903 "%s : update is true, but staParams is NULL. Error!", __func__);
12904 return -EPERM;
12905 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012906
12907 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12908
12909 if (!update)
12910 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012911 /*Before adding sta make sure that device exited from BMPS*/
12912 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12913 {
12914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12915 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12916 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12917 if (status != VOS_STATUS_SUCCESS) {
12918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12919 }
12920 }
12921
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012922 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012923 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012924 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012925 hddLog(VOS_TRACE_LEVEL_ERROR,
12926 FL("Failed to add TDLS peer STA. Enable Bmps"));
12927 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012928 return -EPERM;
12929 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012930 }
12931 else
12932 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012933 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012934 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012935 if (ret != eHAL_STATUS_SUCCESS) {
12936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12937 return -EPERM;
12938 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012939 }
12940
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012941 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012942 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12943
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012944 mutex_lock(&pHddCtx->tdls_lock);
12945 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12946
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012947 if ((pTdlsPeer != NULL) &&
12948 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012949 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012950 hddLog(VOS_TRACE_LEVEL_ERROR,
12951 FL("peer link status %u"), pTdlsPeer->link_status);
12952 mutex_unlock(&pHddCtx->tdls_lock);
12953 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012954 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012955 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012956
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012957 if (ret <= 0)
12958 {
12959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12960 "%s: timeout waiting for tdls add station indication %ld",
12961 __func__, ret);
12962 goto error;
12963 }
12964
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012965 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12966 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012968 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012969 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012970 }
12971
12972 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012973
12974error:
Atul Mittal115287b2014-07-08 13:26:33 +053012975 wlan_hdd_tdls_set_link_status(pAdapter,
12976 mac,
12977 eTDLS_LINK_IDLE,
12978 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012979 return -EPERM;
12980
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012981}
12982#endif
12983
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012984VOS_STATUS wlan_hdd_send_sta_authorized_event(
12985 hdd_adapter_t *adapter,
12986 hdd_context_t *hdd_ctx,
12987 const v_MACADDR_t *mac_addr)
12988{
12989 struct sk_buff *vendor_event;
12990 uint32_t sta_flags = 0;
12991 VOS_STATUS status;
12992
12993 ENTER();
12994
12995 if (!hdd_ctx) {
12996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12997 return -EINVAL;
12998 }
12999
13000 vendor_event =
13001 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013002 hdd_ctx->wiphy,
13003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13004 &adapter->wdev,
13005#endif
13006 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013007 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13008 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13009 GFP_KERNEL);
13010 if (!vendor_event) {
13011 hddLog(VOS_TRACE_LEVEL_ERROR,
13012 FL("cfg80211_vendor_event_alloc failed"));
13013 return -EINVAL;
13014 }
13015
13016 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13017
13018 status = nla_put_u32(vendor_event,
13019 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13020 sta_flags);
13021 if (status) {
13022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13023 kfree_skb(vendor_event);
13024 return VOS_STATUS_E_FAILURE;
13025 }
13026 status = nla_put(vendor_event,
13027 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13028 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13029 if (status) {
13030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13031 kfree_skb(vendor_event);
13032 return VOS_STATUS_E_FAILURE;
13033 }
13034
13035 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13036
13037 EXIT();
13038 return 0;
13039}
13040
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013041static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13044 const u8 *mac,
13045#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013047#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 struct station_parameters *params)
13049{
13050 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013051 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013052 hdd_context_t *pHddCtx;
13053 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013054 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013055 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013056#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013057 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013058 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013059 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013060 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013061#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013062
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013063 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013064
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013065 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013066 if ((NULL == pAdapter))
13067 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013069 "invalid adapter ");
13070 return -EINVAL;
13071 }
13072
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13074 TRACE_CODE_HDD_CHANGE_STATION,
13075 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013077
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013078 ret = wlan_hdd_validate_context(pHddCtx);
13079 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013080 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013081 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013082 }
13083
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013084 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13085
13086 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013087 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13089 "invalid HDD station context");
13090 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013091 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013092 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13093
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013094 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13095 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013097 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013099 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 WLANTL_STA_AUTHENTICATED);
13101
Gopichand Nakkala29149562013-05-10 21:43:41 +053013102 if (status != VOS_STATUS_SUCCESS)
13103 {
13104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13105 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13106 return -EINVAL;
13107 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013108 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13109 &STAMacAddress);
13110 if (status != VOS_STATUS_SUCCESS)
13111 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013112 }
13113 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013114 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13115 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013116#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013117 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13118 StaParams.capability = params->capability;
13119 StaParams.uapsd_queues = params->uapsd_queues;
13120 StaParams.max_sp = params->max_sp;
13121
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013122 /* Convert (first channel , number of channels) tuple to
13123 * the total list of channels. This goes with the assumption
13124 * that if the first channel is < 14, then the next channels
13125 * are an incremental of 1 else an incremental of 4 till the number
13126 * of channels.
13127 */
13128 if (0 != params->supported_channels_len) {
13129 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013130 for ( i = 0 ; i < params->supported_channels_len
13131 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013132 {
13133 int wifi_chan_index;
13134 StaParams.supported_channels[j] = params->supported_channels[i];
13135 wifi_chan_index =
13136 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13137 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013138 for(k=1; k <= no_of_channels
13139 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013140 {
13141 StaParams.supported_channels[j+1] =
13142 StaParams.supported_channels[j] + wifi_chan_index;
13143 j+=1;
13144 }
13145 }
13146 StaParams.supported_channels_len = j;
13147 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013148 if (params->supported_oper_classes_len >
13149 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13151 "received oper classes:%d, resetting it to max supported %d",
13152 params->supported_oper_classes_len,
13153 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13154 params->supported_oper_classes_len =
13155 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13156 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013157 vos_mem_copy(StaParams.supported_oper_classes,
13158 params->supported_oper_classes,
13159 params->supported_oper_classes_len);
13160 StaParams.supported_oper_classes_len =
13161 params->supported_oper_classes_len;
13162
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013163 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13165 "received extn capabilities:%d, resetting it to max supported",
13166 params->ext_capab_len);
13167 params->ext_capab_len = sizeof(StaParams.extn_capability);
13168 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013169 if (0 != params->ext_capab_len)
13170 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013171 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013172
13173 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013174 {
13175 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013176 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013177 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013178
13179 StaParams.supported_rates_len = params->supported_rates_len;
13180
13181 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13182 * The supported_rates array , for all the structures propogating till Add Sta
13183 * to the firmware has to be modified , if the supplicant (ieee80211) is
13184 * modified to send more rates.
13185 */
13186
13187 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13188 */
13189 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13190 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13191
13192 if (0 != StaParams.supported_rates_len) {
13193 int i = 0;
13194 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13195 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013197 "Supported Rates with Length %d", StaParams.supported_rates_len);
13198 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013200 "[%d]: %0x", i, StaParams.supported_rates[i]);
13201 }
13202
13203 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013204 {
13205 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013206 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013207 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013208
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013209 if (0 != params->ext_capab_len ) {
13210 /*Define A Macro : TODO Sunil*/
13211 if ((1<<4) & StaParams.extn_capability[3]) {
13212 isBufSta = 1;
13213 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013214 /* TDLS Channel Switching Support */
13215 if ((1<<6) & StaParams.extn_capability[3]) {
13216 isOffChannelSupported = 1;
13217 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013218 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013219
13220 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013221 (params->ht_capa || params->vht_capa ||
13222 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013223 /* TDLS Peer is WME/QoS capable */
13224 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013225
13226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13227 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13228 __func__, isQosWmmSta, StaParams.htcap_present);
13229
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013230 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13231 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013232 isOffChannelSupported,
13233 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013234
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013235 if (VOS_STATUS_SUCCESS != status) {
13236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13237 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13238 return -EINVAL;
13239 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013240 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13241
13242 if (VOS_STATUS_SUCCESS != status) {
13243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13244 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13245 return -EINVAL;
13246 }
13247 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013248#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013249 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013250 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013251 return status;
13252}
13253
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13255static int wlan_hdd_change_station(struct wiphy *wiphy,
13256 struct net_device *dev,
13257 const u8 *mac,
13258 struct station_parameters *params)
13259#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013260static int wlan_hdd_change_station(struct wiphy *wiphy,
13261 struct net_device *dev,
13262 u8 *mac,
13263 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013264#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013265{
13266 int ret;
13267
13268 vos_ssr_protect(__func__);
13269 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13270 vos_ssr_unprotect(__func__);
13271
13272 return ret;
13273}
13274
Jeff Johnson295189b2012-06-20 16:38:30 -070013275/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013276 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 * This function is used to initialize the key information
13278 */
13279#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013280static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013281 struct net_device *ndev,
13282 u8 key_index, bool pairwise,
13283 const u8 *mac_addr,
13284 struct key_params *params
13285 )
13286#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013287static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013288 struct net_device *ndev,
13289 u8 key_index, const u8 *mac_addr,
13290 struct key_params *params
13291 )
13292#endif
13293{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013295 tCsrRoamSetKey setKey;
13296 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013297 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013298 v_U32_t roamId= 0xFF;
13299 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 hdd_hostapd_state_t *pHostapdState;
13301 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013302 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013303 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013304 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013305 v_MACADDR_t *peerMacAddr;
13306 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013307 uint8_t staid = HDD_MAX_STA_COUNT;
13308 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013309
13310 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013311
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013312 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13313 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13314 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013315 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13316 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013317 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013318 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013319 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013320 }
13321
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13323 __func__, hdd_device_modetoString(pAdapter->device_mode),
13324 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013325
13326 if (CSR_MAX_NUM_KEY <= key_index)
13327 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 key_index);
13330
13331 return -EINVAL;
13332 }
13333
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013334 if (CSR_MAX_KEY_LEN < params->key_len)
13335 {
13336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13337 params->key_len);
13338
13339 return -EINVAL;
13340 }
13341
Jingxiang Gec438aea2017-10-26 16:44:00 +080013342 if (CSR_MAX_RSC_LEN < params->seq_len)
13343 {
13344 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13345 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013346
13347 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013348 }
13349
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013350 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013351 "%s: called with key index = %d & key length %d & seq length %d",
13352 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013353
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013354 peerMacAddr = (v_MACADDR_t *)mac_addr;
13355
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 /*extract key idx, key len and key*/
13357 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13358 setKey.keyId = key_index;
13359 setKey.keyLength = params->key_len;
13360 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013361 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013362
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013363 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 {
13365 case WLAN_CIPHER_SUITE_WEP40:
13366 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13367 break;
13368
13369 case WLAN_CIPHER_SUITE_WEP104:
13370 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13371 break;
13372
13373 case WLAN_CIPHER_SUITE_TKIP:
13374 {
13375 u8 *pKey = &setKey.Key[0];
13376 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13377
13378 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13379
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013380 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013381
13382 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013383 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 |--------------|----------|----------|
13385 <---16bytes---><--8bytes--><--8bytes-->
13386
13387 */
13388 /*Sme expects the 32 bytes key to be in the below order
13389
13390 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013391 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013392 |--------------|----------|----------|
13393 <---16bytes---><--8bytes--><--8bytes-->
13394 */
13395 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013396 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013397
13398 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013399 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013400
13401 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013402 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013403
13404
13405 break;
13406 }
13407
13408 case WLAN_CIPHER_SUITE_CCMP:
13409 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13410 break;
13411
13412#ifdef FEATURE_WLAN_WAPI
13413 case WLAN_CIPHER_SUITE_SMS4:
13414 {
13415 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13416 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13417 params->key, params->key_len);
13418 return 0;
13419 }
13420#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013421
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013422#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 case WLAN_CIPHER_SUITE_KRK:
13424 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13425 break;
13426#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013427
13428#ifdef WLAN_FEATURE_11W
13429 case WLAN_CIPHER_SUITE_AES_CMAC:
13430 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013431 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013432#endif
13433
Jeff Johnson295189b2012-06-20 16:38:30 -070013434 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013437 status = -EOPNOTSUPP;
13438 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 }
13440
13441 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13442 __func__, setKey.encType);
13443
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013444 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13446 (!pairwise)
13447#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013448 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013449#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013450 )
13451 {
13452 /* set group key*/
13453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13454 "%s- %d: setting Broadcast key",
13455 __func__, __LINE__);
13456 setKey.keyDirection = eSIR_RX_ONLY;
13457 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13458 }
13459 else
13460 {
13461 /* set pairwise key*/
13462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13463 "%s- %d: setting pairwise key",
13464 __func__, __LINE__);
13465 setKey.keyDirection = eSIR_TX_RX;
13466 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013467 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013468 }
13469 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13470 {
13471 setKey.keyDirection = eSIR_TX_RX;
13472 /*Set the group key*/
13473 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13474 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013475
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013476 if ( 0 != status )
13477 {
13478 hddLog(VOS_TRACE_LEVEL_ERROR,
13479 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013480 status = -EINVAL;
13481 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013482 }
13483 /*Save the keys here and call sme_RoamSetKey for setting
13484 the PTK after peer joins the IBSS network*/
13485 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13486 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013487 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013488 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013489 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13490 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13491 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013492 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013493 if( pHostapdState->bssState == BSS_START )
13494 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013495 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13496 vos_status = wlan_hdd_check_ula_done(pAdapter);
13497
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013498 if (peerMacAddr && (pairwise_set_key == true))
13499 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013500
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013501 if ( vos_status != VOS_STATUS_SUCCESS )
13502 {
13503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13504 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13505 __LINE__, vos_status );
13506
13507 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13508
13509 status = -EINVAL;
13510 goto end;
13511 }
13512
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13514
13515 if ( status != eHAL_STATUS_SUCCESS )
13516 {
13517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13518 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13519 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013520 status = -EINVAL;
13521 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 }
13523 }
13524
13525 /* Saving WEP keys */
13526 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13527 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13528 {
13529 //Save the wep key in ap context. Issue setkey after the BSS is started.
13530 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13531 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13532 }
13533 else
13534 {
13535 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013536 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13538 }
13539 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013540 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13541 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 {
13543 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13544 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13545
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13547 if (!pairwise)
13548#else
13549 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13550#endif
13551 {
13552 /* set group key*/
13553 if (pHddStaCtx->roam_info.deferKeyComplete)
13554 {
13555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13556 "%s- %d: Perform Set key Complete",
13557 __func__, __LINE__);
13558 hdd_PerformRoamSetKeyComplete(pAdapter);
13559 }
13560 }
13561
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013562 if (pairwise_set_key == true)
13563 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013564
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13566
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013567 pWextState->roamProfile.Keys.defaultIndex = key_index;
13568
13569
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013570 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 params->key, params->key_len);
13572
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013573
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13575
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013576 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013577 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013578 __func__, setKey.peerMac[0], setKey.peerMac[1],
13579 setKey.peerMac[2], setKey.peerMac[3],
13580 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 setKey.keyDirection);
13582
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013583 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013584
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013585 if ( vos_status != VOS_STATUS_SUCCESS )
13586 {
13587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13589 __LINE__, vos_status );
13590
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013591 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013592
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013593 status = -EINVAL;
13594 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013595
13596 }
13597
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013598#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013599 /* The supplicant may attempt to set the PTK once pre-authentication
13600 is done. Save the key in the UMAC and include it in the ADD BSS
13601 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013602 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013603 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013604 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013605 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13606 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013607 status = 0;
13608 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013609 }
13610 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13611 {
13612 hddLog(VOS_TRACE_LEVEL_ERROR,
13613 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013614 status = -EINVAL;
13615 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013616 }
13617#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013618
13619 /* issue set key request to SME*/
13620 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13621 pAdapter->sessionId, &setKey, &roamId );
13622
13623 if ( 0 != status )
13624 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013625 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13627 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013628 status = -EINVAL;
13629 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013630 }
13631
13632
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013633 /* in case of IBSS as there was no information available about WEP keys during
13634 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013635 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013636 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13637 !( ( IW_AUTH_KEY_MGMT_802_1X
13638 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13640 )
13641 &&
13642 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13643 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13644 )
13645 )
13646 {
13647 setKey.keyDirection = eSIR_RX_ONLY;
13648 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13649
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013650 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013652 __func__, setKey.peerMac[0], setKey.peerMac[1],
13653 setKey.peerMac[2], setKey.peerMac[3],
13654 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013655 setKey.keyDirection);
13656
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013657 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 pAdapter->sessionId, &setKey, &roamId );
13659
13660 if ( 0 != status )
13661 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662 hddLog(VOS_TRACE_LEVEL_ERROR,
13663 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013664 __func__, status);
13665 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013666 status = -EINVAL;
13667 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 }
13669 }
13670 }
13671
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013672 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013673 for (i = 0; i < params->seq_len; i++) {
13674 rsc_counter |= (params->seq[i] << i*8);
13675 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013676 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13677 }
13678
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013679end:
13680 /* Need to clear any trace of key value in the memory.
13681 * Thus zero out the memory even though it is local
13682 * variable.
13683 */
13684 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013685 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013686 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013687}
13688
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13690static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13691 struct net_device *ndev,
13692 u8 key_index, bool pairwise,
13693 const u8 *mac_addr,
13694 struct key_params *params
13695 )
13696#else
13697static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13698 struct net_device *ndev,
13699 u8 key_index, const u8 *mac_addr,
13700 struct key_params *params
13701 )
13702#endif
13703{
13704 int ret;
13705 vos_ssr_protect(__func__);
13706#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13707 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13708 mac_addr, params);
13709#else
13710 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13711 params);
13712#endif
13713 vos_ssr_unprotect(__func__);
13714
13715 return ret;
13716}
13717
Jeff Johnson295189b2012-06-20 16:38:30 -070013718/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013719 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 * This function is used to get the key information
13721 */
13722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013723static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013724 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013726 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 const u8 *mac_addr, void *cookie,
13728 void (*callback)(void *cookie, struct key_params*)
13729 )
13730#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013731static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 struct net_device *ndev,
13734 u8 key_index, const u8 *mac_addr, void *cookie,
13735 void (*callback)(void *cookie, struct key_params*)
13736 )
13737#endif
13738{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013739 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013740 hdd_wext_state_t *pWextState = NULL;
13741 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013743 hdd_context_t *pHddCtx;
13744 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013745
13746 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013747
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013748 if (NULL == pAdapter)
13749 {
13750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13751 "%s: HDD adapter is Null", __func__);
13752 return -ENODEV;
13753 }
13754
13755 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13756 ret = wlan_hdd_validate_context(pHddCtx);
13757 if (0 != ret)
13758 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013759 return ret;
13760 }
13761
13762 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13763 pRoamProfile = &(pWextState->roamProfile);
13764
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013765 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13766 __func__, hdd_device_modetoString(pAdapter->device_mode),
13767 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013768
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 memset(&params, 0, sizeof(params));
13770
13771 if (CSR_MAX_NUM_KEY <= key_index)
13772 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013774 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013775 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013776
13777 switch(pRoamProfile->EncryptionType.encryptionType[0])
13778 {
13779 case eCSR_ENCRYPT_TYPE_NONE:
13780 params.cipher = IW_AUTH_CIPHER_NONE;
13781 break;
13782
13783 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13784 case eCSR_ENCRYPT_TYPE_WEP40:
13785 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13786 break;
13787
13788 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13789 case eCSR_ENCRYPT_TYPE_WEP104:
13790 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13791 break;
13792
13793 case eCSR_ENCRYPT_TYPE_TKIP:
13794 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13795 break;
13796
13797 case eCSR_ENCRYPT_TYPE_AES:
13798 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13799 break;
13800
13801 default:
13802 params.cipher = IW_AUTH_CIPHER_NONE;
13803 break;
13804 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013805
c_hpothuaaf19692014-05-17 17:01:48 +053013806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13807 TRACE_CODE_HDD_CFG80211_GET_KEY,
13808 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013809
Jeff Johnson295189b2012-06-20 16:38:30 -070013810 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13811 params.seq_len = 0;
13812 params.seq = NULL;
13813 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13814 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013815 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013816 return 0;
13817}
13818
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13820static int wlan_hdd_cfg80211_get_key(
13821 struct wiphy *wiphy,
13822 struct net_device *ndev,
13823 u8 key_index, bool pairwise,
13824 const u8 *mac_addr, void *cookie,
13825 void (*callback)(void *cookie, struct key_params*)
13826 )
13827#else
13828static int wlan_hdd_cfg80211_get_key(
13829 struct wiphy *wiphy,
13830 struct net_device *ndev,
13831 u8 key_index, const u8 *mac_addr, void *cookie,
13832 void (*callback)(void *cookie, struct key_params*)
13833 )
13834#endif
13835{
13836 int ret;
13837
13838 vos_ssr_protect(__func__);
13839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13840 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13841 mac_addr, cookie, callback);
13842#else
13843 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13844 callback);
13845#endif
13846 vos_ssr_unprotect(__func__);
13847
13848 return ret;
13849}
13850
Jeff Johnson295189b2012-06-20 16:38:30 -070013851/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013852 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 * This function is used to delete the key information
13854 */
13855#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013856static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013858 u8 key_index,
13859 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 const u8 *mac_addr
13861 )
13862#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013863static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013864 struct net_device *ndev,
13865 u8 key_index,
13866 const u8 *mac_addr
13867 )
13868#endif
13869{
13870 int status = 0;
13871
13872 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013873 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 //it is observed that this is invalidating peer
13875 //key index whenever re-key is done. This is affecting data link.
13876 //It should be ok to ignore del_key.
13877#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13879 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13881 tCsrRoamSetKey setKey;
13882 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013883
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 ENTER();
13885
13886 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13887 __func__,pAdapter->device_mode);
13888
13889 if (CSR_MAX_NUM_KEY <= key_index)
13890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 key_index);
13893
13894 return -EINVAL;
13895 }
13896
13897 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13898 setKey.keyId = key_index;
13899
13900 if (mac_addr)
13901 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13902 else
13903 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13904
13905 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13906
13907 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013909 )
13910 {
13911
13912 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13914 if( pHostapdState->bssState == BSS_START)
13915 {
13916 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013917
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 if ( status != eHAL_STATUS_SUCCESS )
13919 {
13920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13921 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13922 __LINE__, status );
13923 }
13924 }
13925 }
13926 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013927 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 )
13929 {
13930 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13931
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013932 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13933
13934 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013936 __func__, setKey.peerMac[0], setKey.peerMac[1],
13937 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939 if(pAdapter->sessionCtx.station.conn_info.connState ==
13940 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013942 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013944
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 if ( 0 != status )
13946 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013947 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 "%s: sme_RoamSetKey failure, returned %d",
13949 __func__, status);
13950 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13951 return -EINVAL;
13952 }
13953 }
13954 }
13955#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013956 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 return status;
13958}
13959
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013960#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13961static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13962 struct net_device *ndev,
13963 u8 key_index,
13964 bool pairwise,
13965 const u8 *mac_addr
13966 )
13967#else
13968static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13969 struct net_device *ndev,
13970 u8 key_index,
13971 const u8 *mac_addr
13972 )
13973#endif
13974{
13975 int ret;
13976
13977 vos_ssr_protect(__func__);
13978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13979 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13980 mac_addr);
13981#else
13982 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13983#endif
13984 vos_ssr_unprotect(__func__);
13985
13986 return ret;
13987}
13988
Jeff Johnson295189b2012-06-20 16:38:30 -070013989/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013990 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 * This function is used to set the default tx key index
13992 */
13993#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
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 bool unicast, bool multicast)
13998#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013999static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 struct net_device *ndev,
14001 u8 key_index)
14002#endif
14003{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014005 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014006 hdd_wext_state_t *pWextState;
14007 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014008 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014009
14010 ENTER();
14011
Gopichand Nakkala29149562013-05-10 21:43:41 +053014012 if ((NULL == pAdapter))
14013 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014015 "invalid adapter");
14016 return -EINVAL;
14017 }
14018
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014019 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14020 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14021 pAdapter->sessionId, key_index));
14022
Gopichand Nakkala29149562013-05-10 21:43:41 +053014023 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14024 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14025
14026 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14027 {
14028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14029 "invalid Wext state or HDD context");
14030 return -EINVAL;
14031 }
14032
Arif Hussain6d2a3322013-11-17 19:50:10 -080014033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014035
Jeff Johnson295189b2012-06-20 16:38:30 -070014036 if (CSR_MAX_NUM_KEY <= key_index)
14037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014039 key_index);
14040
14041 return -EINVAL;
14042 }
14043
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014044 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14045 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014046 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014047 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014048 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014049 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014050
Jeff Johnson295189b2012-06-20 16:38:30 -070014051 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014053 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014055 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014056 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014057#ifdef FEATURE_WLAN_WAPI
14058 (eCSR_ENCRYPT_TYPE_WPI !=
14059 pHddStaCtx->conn_info.ucEncryptionType) &&
14060#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014062 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014063 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014064 {
14065 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014067
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 tCsrRoamSetKey setKey;
14069 v_U32_t roamId= 0xFF;
14070 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014071
14072 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014074
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 Keys->defaultIndex = (u8)key_index;
14076 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14077 setKey.keyId = key_index;
14078 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014079
14080 vos_mem_copy(&setKey.Key[0],
14081 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014083
Gopichand Nakkala29149562013-05-10 21:43:41 +053014084 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085
14086 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014087 &pHddStaCtx->conn_info.bssId[0],
14088 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014089
Gopichand Nakkala29149562013-05-10 21:43:41 +053014090 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14091 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14092 eCSR_ENCRYPT_TYPE_WEP104)
14093 {
14094 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14095 even though ap is configured for WEP-40 encryption. In this canse the key length
14096 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14097 type(104) and switching encryption type to 40*/
14098 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14099 eCSR_ENCRYPT_TYPE_WEP40;
14100 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14101 eCSR_ENCRYPT_TYPE_WEP40;
14102 }
14103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014104 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014106
Jeff Johnson295189b2012-06-20 16:38:30 -070014107 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014110
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 if ( 0 != status )
14112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113 hddLog(VOS_TRACE_LEVEL_ERROR,
14114 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014115 status);
14116 return -EINVAL;
14117 }
14118 }
14119 }
14120
14121 /* In SoftAp mode setting key direction for default mode */
14122 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14123 {
14124 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14125 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14126 (eCSR_ENCRYPT_TYPE_AES !=
14127 pWextState->roamProfile.EncryptionType.encryptionType[0])
14128 )
14129 {
14130 /* Saving key direction for default key index to TX default */
14131 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14132 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14133 }
14134 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014135 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014136 return status;
14137}
14138
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14140static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14141 struct net_device *ndev,
14142 u8 key_index,
14143 bool unicast, bool multicast)
14144#else
14145static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14146 struct net_device *ndev,
14147 u8 key_index)
14148#endif
14149{
14150 int ret;
14151 vos_ssr_protect(__func__);
14152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14153 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14154 multicast);
14155#else
14156 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14157#endif
14158 vos_ssr_unprotect(__func__);
14159
14160 return ret;
14161}
14162
Jeff Johnson295189b2012-06-20 16:38:30 -070014163/*
14164 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14165 * This function is used to inform the BSS details to nl80211 interface.
14166 */
14167static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14168 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14169{
14170 struct net_device *dev = pAdapter->dev;
14171 struct wireless_dev *wdev = dev->ieee80211_ptr;
14172 struct wiphy *wiphy = wdev->wiphy;
14173 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14174 int chan_no;
14175 int ie_length;
14176 const char *ie;
14177 unsigned int freq;
14178 struct ieee80211_channel *chan;
14179 int rssi = 0;
14180 struct cfg80211_bss *bss = NULL;
14181
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 if( NULL == pBssDesc )
14183 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014184 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 return bss;
14186 }
14187
14188 chan_no = pBssDesc->channelId;
14189 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14190 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14191
14192 if( NULL == ie )
14193 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014194 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 return bss;
14196 }
14197
14198#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14199 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14200 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014201 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014202 }
14203 else
14204 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014205 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014206 }
14207#else
14208 freq = ieee80211_channel_to_frequency(chan_no);
14209#endif
14210
14211 chan = __ieee80211_get_channel(wiphy, freq);
14212
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014213 if (!chan) {
14214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14215 return NULL;
14216 }
14217
Abhishek Singhaee43942014-06-16 18:55:47 +053014218 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014219
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014220 return cfg80211_inform_bss(wiphy, chan,
14221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14222 CFG80211_BSS_FTYPE_UNKNOWN,
14223#endif
14224 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014225 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014226 pBssDesc->capabilityInfo,
14227 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014228 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014229}
14230
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014231/*
14232 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14233 * interface that BSS might have been lost.
14234 * @pAdapter: adaptor
14235 * @bssid: bssid which might have been lost
14236 *
14237 * Return: bss which is unlinked from kernel cache
14238 */
14239struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14240 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14241{
14242 struct net_device *dev = pAdapter->dev;
14243 struct wireless_dev *wdev = dev->ieee80211_ptr;
14244 struct wiphy *wiphy = wdev->wiphy;
14245 struct cfg80211_bss *bss = NULL;
14246
Abhishek Singh5a597e62016-12-05 15:16:30 +053014247 bss = hdd_get_bss_entry(wiphy,
14248 NULL, bssid,
14249 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014250 if (bss == NULL) {
14251 hddLog(LOGE, FL("BSS not present"));
14252 } else {
14253 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14254 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14255 cfg80211_unlink_bss(wiphy, bss);
14256 }
14257 return bss;
14258}
Jeff Johnson295189b2012-06-20 16:38:30 -070014259
14260
14261/*
14262 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14263 * This function is used to inform the BSS details to nl80211 interface.
14264 */
14265struct cfg80211_bss*
14266wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14267 tSirBssDescription *bss_desc
14268 )
14269{
14270 /*
14271 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14272 already exists in bss data base of cfg80211 for that particular BSS ID.
14273 Using cfg80211_inform_bss_frame to update the bss entry instead of
14274 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14275 now there is no possibility to get the mgmt(probe response) frame from PE,
14276 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14277 cfg80211_inform_bss_frame.
14278 */
14279 struct net_device *dev = pAdapter->dev;
14280 struct wireless_dev *wdev = dev->ieee80211_ptr;
14281 struct wiphy *wiphy = wdev->wiphy;
14282 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014283#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14284 qcom_ie_age *qie_age = NULL;
14285 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14286#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014288#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 const char *ie =
14290 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14291 unsigned int freq;
14292 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014293 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014294 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014295 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14296 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014297 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014298 hdd_context_t *pHddCtx;
14299 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014300#ifdef WLAN_OPEN_SOURCE
14301 struct timespec ts;
14302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014303
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014304
Wilson Yangf80a0542013-10-07 13:02:37 -070014305 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14306 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014307 if (0 != status)
14308 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014309 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014310 }
14311
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014312 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014313 if (!mgmt)
14314 {
14315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14316 "%s: memory allocation failed ", __func__);
14317 return NULL;
14318 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014319
Jeff Johnson295189b2012-06-20 16:38:30 -070014320 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014321
14322#ifdef WLAN_OPEN_SOURCE
14323 /* Android does not want the timestamp from the frame.
14324 Instead it wants a monotonic increasing value */
14325 get_monotonic_boottime(&ts);
14326 mgmt->u.probe_resp.timestamp =
14327 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14328#else
14329 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014330 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14331 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014332
14333#endif
14334
Jeff Johnson295189b2012-06-20 16:38:30 -070014335 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14336 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014337
14338#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14339 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14340 /* Assuming this is the last IE, copy at the end */
14341 ie_length -=sizeof(qcom_ie_age);
14342 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14343 qie_age->element_id = QCOM_VENDOR_IE_ID;
14344 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14345 qie_age->oui_1 = QCOM_OUI1;
14346 qie_age->oui_2 = QCOM_OUI2;
14347 qie_age->oui_3 = QCOM_OUI3;
14348 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014349 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14350 * bss related timestamp is in units of ms. Due to this when scan results
14351 * are sent to lowi the scan age is high.To address this, send age in units
14352 * of 1/10 ms.
14353 */
14354 qie_age->age = (vos_timer_get_system_time() -
14355 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014356#endif
14357
Jeff Johnson295189b2012-06-20 16:38:30 -070014358 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014359 if (bss_desc->fProbeRsp)
14360 {
14361 mgmt->frame_control |=
14362 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14363 }
14364 else
14365 {
14366 mgmt->frame_control |=
14367 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14368 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014369
14370#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014371 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014372 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014373 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014374 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014375 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014376 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014377 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014378
14379 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014380 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014381 }
14382 else
14383 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014384 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14385 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014386 kfree(mgmt);
14387 return NULL;
14388 }
14389#else
14390 freq = ieee80211_channel_to_frequency(chan_no);
14391#endif
14392 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014393 /*when the band is changed on the fly using the GUI, three things are done
14394 * 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)
14395 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14396 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14397 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14398 * and discards the channels correponding to previous band and calls back with zero bss results.
14399 * 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
14400 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14401 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14402 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14403 * So drop the bss and continue to next bss.
14404 */
14405 if(chan == NULL)
14406 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014407 hddLog(VOS_TRACE_LEVEL_ERROR,
14408 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14409 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014410 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014411 return NULL;
14412 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014413 /*To keep the rssi icon of the connected AP in the scan window
14414 *and the rssi icon of the wireless networks in sync
14415 * */
14416 if (( eConnectionState_Associated ==
14417 pAdapter->sessionCtx.station.conn_info.connState ) &&
14418 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14419 pAdapter->sessionCtx.station.conn_info.bssId,
14420 WNI_CFG_BSSID_LEN)) &&
14421 (pHddCtx->hdd_wlan_suspended == FALSE))
14422 {
14423 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14424 rssi = (pAdapter->rssi * 100);
14425 }
14426 else
14427 {
14428 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014430
Nirav Shah20ac06f2013-12-12 18:14:06 +053014431 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014432 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14433 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014434
Jeff Johnson295189b2012-06-20 16:38:30 -070014435 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14436 frame_len, rssi, GFP_KERNEL);
14437 kfree(mgmt);
14438 return bss_status;
14439}
14440
14441/*
14442 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14443 * This function is used to update the BSS data base of CFG8011
14444 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014445struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014446 tCsrRoamInfo *pRoamInfo
14447 )
14448{
14449 tCsrRoamConnectedProfile roamProfile;
14450 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14451 struct cfg80211_bss *bss = NULL;
14452
14453 ENTER();
14454
14455 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14456 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14457
14458 if (NULL != roamProfile.pBssDesc)
14459 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014460 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14461 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014462
14463 if (NULL == bss)
14464 {
14465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14466 __func__);
14467 }
14468
14469 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14470 }
14471 else
14472 {
14473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14474 __func__);
14475 }
14476 return bss;
14477}
14478
14479/*
14480 * FUNCTION: wlan_hdd_cfg80211_update_bss
14481 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014482static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14483 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014484 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014485{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014486 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014487 tCsrScanResultInfo *pScanResult;
14488 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014489 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 tScanResultHandle pResult;
14491 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014492 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014493 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014494 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014495
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014496 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14497 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14498 NO_SESSION, pAdapter->sessionId));
14499
Wilson Yangf80a0542013-10-07 13:02:37 -070014500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014501 ret = wlan_hdd_validate_context(pHddCtx);
14502 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014504 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014505 }
14506
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014507 if (pAdapter->request != NULL)
14508 {
14509 if ((pAdapter->request->n_ssids == 1)
14510 && (pAdapter->request->ssids != NULL)
14511 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14512 is_p2p_scan = true;
14513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 /*
14515 * start getting scan results and populate cgf80211 BSS database
14516 */
14517 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14518
14519 /* no scan results */
14520 if (NULL == pResult)
14521 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14523 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014524 wlan_hdd_get_frame_logs(pAdapter,
14525 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014526 return status;
14527 }
14528
14529 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14530
14531 while (pScanResult)
14532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014533 /*
14534 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14535 * entry already exists in bss data base of cfg80211 for that
14536 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14537 * bss entry instead of cfg80211_inform_bss, But this call expects
14538 * mgmt packet as input. As of now there is no possibility to get
14539 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014540 * ieee80211_mgmt(probe response) and passing to c
14541 * fg80211_inform_bss_frame.
14542 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014543 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14544 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14545 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014546 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14547 continue; //Skip the non p2p bss entries
14548 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014549 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14550 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014551
Jeff Johnson295189b2012-06-20 16:38:30 -070014552
14553 if (NULL == bss_status)
14554 {
14555 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014556 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014557 }
14558 else
14559 {
Yue Maf49ba872013-08-19 12:04:25 -070014560 cfg80211_put_bss(
14561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14562 wiphy,
14563#endif
14564 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014565 }
14566
14567 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14568 }
14569
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014570 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014571 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014572 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014573}
14574
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014575void
14576hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14577{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014578 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014579 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014580} /****** end hddPrintMacAddr() ******/
14581
14582void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014583hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014584{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014585 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014586 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014587 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14588 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14589 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014590} /****** end hddPrintPmkId() ******/
14591
14592//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14593//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14594
14595//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14596//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14597
14598#define dump_bssid(bssid) \
14599 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014600 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14601 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014602 }
14603
14604#define dump_pmkid(pMac, pmkid) \
14605 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014606 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14607 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014608 }
14609
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014610#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014611/*
14612 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14613 * This function is used to notify the supplicant of a new PMKSA candidate.
14614 */
14615int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014616 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014617 int index, bool preauth )
14618{
Jeff Johnsone7245742012-09-05 17:12:55 -070014619#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014620 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014621 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014622
14623 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014624 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014625
14626 if( NULL == pRoamInfo )
14627 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014628 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014629 return -EINVAL;
14630 }
14631
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014632 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14633 {
14634 dump_bssid(pRoamInfo->bssid);
14635 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014636 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014637 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014638#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014639 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014640}
14641#endif //FEATURE_WLAN_LFR
14642
Yue Maef608272013-04-08 23:09:17 -070014643#ifdef FEATURE_WLAN_LFR_METRICS
14644/*
14645 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14646 * 802.11r/LFR metrics reporting function to report preauth initiation
14647 *
14648 */
14649#define MAX_LFR_METRICS_EVENT_LENGTH 100
14650VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14651 tCsrRoamInfo *pRoamInfo)
14652{
14653 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14654 union iwreq_data wrqu;
14655
14656 ENTER();
14657
14658 if (NULL == pAdapter)
14659 {
14660 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14661 return VOS_STATUS_E_FAILURE;
14662 }
14663
14664 /* create the event */
14665 memset(&wrqu, 0, sizeof(wrqu));
14666 memset(metrics_notification, 0, sizeof(metrics_notification));
14667
14668 wrqu.data.pointer = metrics_notification;
14669 wrqu.data.length = scnprintf(metrics_notification,
14670 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14671 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14672
14673 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14674
14675 EXIT();
14676
14677 return VOS_STATUS_SUCCESS;
14678}
14679
14680/*
14681 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14682 * 802.11r/LFR metrics reporting function to report preauth completion
14683 * or failure
14684 */
14685VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14686 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14687{
14688 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14689 union iwreq_data wrqu;
14690
14691 ENTER();
14692
14693 if (NULL == pAdapter)
14694 {
14695 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14696 return VOS_STATUS_E_FAILURE;
14697 }
14698
14699 /* create the event */
14700 memset(&wrqu, 0, sizeof(wrqu));
14701 memset(metrics_notification, 0, sizeof(metrics_notification));
14702
14703 scnprintf(metrics_notification, sizeof(metrics_notification),
14704 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14705 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14706
14707 if (1 == preauth_status)
14708 strncat(metrics_notification, " TRUE", 5);
14709 else
14710 strncat(metrics_notification, " FALSE", 6);
14711
14712 wrqu.data.pointer = metrics_notification;
14713 wrqu.data.length = strlen(metrics_notification);
14714
14715 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14716
14717 EXIT();
14718
14719 return VOS_STATUS_SUCCESS;
14720}
14721
14722/*
14723 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14724 * 802.11r/LFR metrics reporting function to report handover initiation
14725 *
14726 */
14727VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14728 tCsrRoamInfo *pRoamInfo)
14729{
14730 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14731 union iwreq_data wrqu;
14732
14733 ENTER();
14734
14735 if (NULL == pAdapter)
14736 {
14737 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14738 return VOS_STATUS_E_FAILURE;
14739 }
14740
14741 /* create the event */
14742 memset(&wrqu, 0, sizeof(wrqu));
14743 memset(metrics_notification, 0, sizeof(metrics_notification));
14744
14745 wrqu.data.pointer = metrics_notification;
14746 wrqu.data.length = scnprintf(metrics_notification,
14747 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14748 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14749
14750 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14751
14752 EXIT();
14753
14754 return VOS_STATUS_SUCCESS;
14755}
14756#endif
14757
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014758
14759/**
14760 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14761 * @scan_req: scan request to be checked
14762 *
14763 * Return: true or false
14764 */
14765#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14766static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14767 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014768 *scan_req, hdd_context_t
14769 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014770{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014771 if (!scan_req || !scan_req->wiphy ||
14772 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014773 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14774 return false;
14775 }
14776 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14777 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14778 return false;
14779 }
14780 return true;
14781}
14782#else
14783static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14784 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014785 *scan_req, hdd_context_t
14786 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014787{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014788 if (!scan_req || !scan_req->wiphy ||
14789 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014790 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14791 return false;
14792 }
14793 return true;
14794}
14795#endif
14796
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14798/**
14799 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14800 * @adapter: Pointer to the adapter
14801 * @req : Scan request
14802 * @aborted : true scan aborted false scan success
14803 *
14804 * This function notifies scan done to cfg80211
14805 *
14806 * Return: none
14807 */
14808static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14809 struct cfg80211_scan_request *req,
14810 bool aborted)
14811{
14812 struct cfg80211_scan_info info = {
14813 .aborted = aborted
14814 };
14815
14816 if (adapter->dev->flags & IFF_UP)
14817 cfg80211_scan_done(req, &info);
14818 else
14819 hddLog(LOGW,
14820 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14821}
14822#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14823/**
14824 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14825 * @adapter: Pointer to the adapter
14826 * @req : Scan request
14827 * @aborted : true scan aborted false scan success
14828 *
14829 * This function notifies scan done to cfg80211
14830 *
14831 * Return: none
14832 */
14833static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14834 struct cfg80211_scan_request *req,
14835 bool aborted)
14836{
14837 if (adapter->dev->flags & IFF_UP)
14838 cfg80211_scan_done(req, aborted);
14839 else
14840 hddLog(LOGW,
14841 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14842}
14843#else
14844/**
14845 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14846 * @adapter: Pointer to the adapter
14847 * @req : Scan request
14848 * @aborted : true scan aborted false scan success
14849 *
14850 * This function notifies scan done to cfg80211
14851 *
14852 * Return: none
14853 */
14854static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14855 struct cfg80211_scan_request *req,
14856 bool aborted)
14857{
14858 cfg80211_scan_done(req, aborted);
14859}
14860#endif
14861
Mukul Sharmab392b642017-08-17 17:45:29 +053014862#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014863/*
14864 * FUNCTION: hdd_cfg80211_scan_done_callback
14865 * scanning callback function, called after finishing scan
14866 *
14867 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014868static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014869 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14870{
14871 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014872 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014874 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014875 struct cfg80211_scan_request *req = NULL;
14876 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014877 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014878 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014879 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014880
14881 ENTER();
14882
c_manjee1b4ab9a2016-10-26 11:36:55 +053014883 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14884 !pAdapter->dev) {
14885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14886 return 0;
14887 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014889 if (NULL == pHddCtx) {
14890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014891 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014892 }
14893
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014895 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014896 {
14897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014898 }
14899#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014900 pScanInfo = &pHddCtx->scan_info;
14901
Jeff Johnson295189b2012-06-20 16:38:30 -070014902 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014903 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014904 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014905 __func__, halHandle, pContext, (int) scanId, (int) status);
14906
Kiet Lamac06e2c2013-10-23 16:25:07 +053014907 pScanInfo->mScanPendingCounter = 0;
14908
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014910 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014911 &pScanInfo->scan_req_completion_event,
14912 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014913 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014914 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014915 hddLog(VOS_TRACE_LEVEL_ERROR,
14916 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014918 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 }
14920
Yue Maef608272013-04-08 23:09:17 -070014921 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 {
14923 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014924 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014925 }
14926
14927 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014928 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 {
14930 hddLog(VOS_TRACE_LEVEL_INFO,
14931 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014932 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 (int) scanId);
14934 }
14935
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014936#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014937 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014938#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014939 {
14940 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14941 pAdapter);
14942 if (0 > ret)
14943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014944 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014945
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 /* If any client wait scan result through WEXT
14947 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014948 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 {
14950 /* The other scan request waiting for current scan finish
14951 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014952 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014954 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014955 }
14956 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014957 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 {
14959 struct net_device *dev = pAdapter->dev;
14960 union iwreq_data wrqu;
14961 int we_event;
14962 char *msg;
14963
14964 memset(&wrqu, '\0', sizeof(wrqu));
14965 we_event = SIOCGIWSCAN;
14966 msg = NULL;
14967 wireless_send_event(dev, we_event, &wrqu, msg);
14968 }
14969 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014970 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014971
14972 /* Get the Scan Req */
14973 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014974 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014975
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014976 /* Scan is no longer pending */
14977 pScanInfo->mScanPending = VOS_FALSE;
14978
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014979 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014980 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014983 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014984#endif
14985
14986 if (pAdapter->dev) {
14987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14988 pAdapter->dev->name);
14989 }
mukul sharmae7041822015-12-03 15:09:21 +053014990 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014991 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014992 }
14993
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014994 /* last_scan_timestamp is used to decide if new scan
14995 * is needed or not on station interface. If last station
14996 * scan time and new station scan time is less then
14997 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014998 * Also only last_scan_timestamp is updated here last_scan_channellist
14999 * is updated on receiving scan request itself to make sure kernel
15000 * allocated scan request(scan_req) object is not dereferenced here,
15001 * because interface down, where kernel frees scan_req, may happen any
15002 * time while driver is processing scan_done_callback. So it's better
15003 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015004 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015005 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15006 if (status == eCSR_SCAN_SUCCESS)
15007 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15008 else {
15009 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15010 sizeof(pHddCtx->scan_info.last_scan_channelList));
15011 pHddCtx->scan_info.last_scan_numChannels = 0;
15012 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015013 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015014 }
15015
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015016 /*
15017 * cfg80211_scan_done informing NL80211 about completion
15018 * of scanning
15019 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015020 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15021 {
15022 aborted = true;
15023 }
mukul sharmae7041822015-12-03 15:09:21 +053015024
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015026 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15027 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015028#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015029 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015030
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015031 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015032
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015033allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015034 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15035 ) && (pHddCtx->spoofMacAddr.isEnabled
15036 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015037 /* Generate new random mac addr for next scan */
15038 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015039
15040 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15041 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015042 }
15043
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015044 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015045 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015046
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015047 /* Acquire wakelock to handle the case where APP's tries to suspend
15048 * immediatly after the driver gets connect request(i.e after scan)
15049 * from supplicant, this result in app's is suspending and not able
15050 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015051 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015052
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015054 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015055#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015056#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015057 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015058#endif
15059
Jeff Johnson295189b2012-06-20 16:38:30 -070015060 EXIT();
15061 return 0;
15062}
15063
15064/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015065 * FUNCTION: hdd_isConnectionInProgress
15066 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015067 *
15068 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015069v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15070 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015071{
15072 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15073 hdd_station_ctx_t *pHddStaCtx = NULL;
15074 hdd_adapter_t *pAdapter = NULL;
15075 VOS_STATUS status = 0;
15076 v_U8_t staId = 0;
15077 v_U8_t *staMac = NULL;
15078
15079 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15080
15081 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15082 {
15083 pAdapter = pAdapterNode->pAdapter;
15084
15085 if( pAdapter )
15086 {
15087 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015088 "%s: Adapter with device mode %s (%d) exists",
15089 __func__, hdd_device_modetoString(pAdapter->device_mode),
15090 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015091 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015092 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15093 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15094 (eConnectionState_Connecting ==
15095 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15096 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015097 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015098 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015099 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015100 if (session_id && reason)
15101 {
15102 *session_id = pAdapter->sessionId;
15103 *reason = eHDD_CONNECTION_IN_PROGRESS;
15104 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015105 return VOS_TRUE;
15106 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015107 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015108 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015109 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015110 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015111 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015112 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015113 if (session_id && reason)
15114 {
15115 *session_id = pAdapter->sessionId;
15116 *reason = eHDD_REASSOC_IN_PROGRESS;
15117 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015118 return VOS_TRUE;
15119 }
15120 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015121 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15122 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015123 {
15124 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15125 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015126 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15127 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015128 {
15129 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015130 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015131 "%s: client " MAC_ADDRESS_STR
15132 " is in the middle of WPS/EAPOL exchange.", __func__,
15133 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015134 if (session_id && reason)
15135 {
15136 *session_id = pAdapter->sessionId;
15137 *reason = eHDD_EAPOL_IN_PROGRESS;
15138 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015139 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015140 }
15141 }
15142 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15143 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15144 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015145 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15146 ptSapContext pSapCtx = NULL;
15147 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15148 if(pSapCtx == NULL){
15149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15150 FL("psapCtx is NULL"));
15151 return VOS_FALSE;
15152 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015153 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15154 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015155 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15156 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015157 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015158 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015159
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015160 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015161 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15162 "middle of WPS/EAPOL exchange.", __func__,
15163 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015164 if (session_id && reason)
15165 {
15166 *session_id = pAdapter->sessionId;
15167 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15168 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015169 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015170 }
15171 }
15172 }
15173 }
15174 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15175 pAdapterNode = pNext;
15176 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015177 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015178}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015179
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015180/**
15181 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15182 * to the Scan request
15183 * @scanRequest: Pointer to the csr scan request
15184 * @request: Pointer to the scan request from supplicant
15185 *
15186 * Return: None
15187 */
15188#ifdef CFG80211_SCAN_BSSID
15189static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15190 struct cfg80211_scan_request *request)
15191{
15192 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15193}
15194#else
15195static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15196 struct cfg80211_scan_request *request)
15197{
15198}
15199#endif
15200
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015201/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015202 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015203 * this scan respond to scan trigger and update cfg80211 scan database
15204 * later, scan dump command can be used to recieve scan results
15205 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015206int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015207#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15208 struct net_device *dev,
15209#endif
15210 struct cfg80211_scan_request *request)
15211{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015212 hdd_adapter_t *pAdapter = NULL;
15213 hdd_context_t *pHddCtx = NULL;
15214 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015215 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 tCsrScanRequest scanRequest;
15217 tANI_U8 *channelList = NULL, i;
15218 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015219 int status;
15220 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015222 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015223 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015224 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015225 v_U8_t curr_session_id;
15226 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015227
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15229 struct net_device *dev = NULL;
15230 if (NULL == request)
15231 {
15232 hddLog(VOS_TRACE_LEVEL_ERROR,
15233 "%s: scan req param null", __func__);
15234 return -EINVAL;
15235 }
15236 dev = request->wdev->netdev;
15237#endif
15238
15239 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15240 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15241 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15242
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 ENTER();
15244
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015245 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15246 __func__, hdd_device_modetoString(pAdapter->device_mode),
15247 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015248
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015249 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015250 if (0 != status)
15251 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015252 return status;
15253 }
15254
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015255 if (NULL == pwextBuf)
15256 {
15257 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15258 __func__);
15259 return -EIO;
15260 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015261 cfg_param = pHddCtx->cfg_ini;
15262 pScanInfo = &pHddCtx->scan_info;
15263
Jeff Johnson295189b2012-06-20 16:38:30 -070015264#ifdef WLAN_BTAMP_FEATURE
15265 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015266 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015267 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015268 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 "%s: No scanning when AMP is on", __func__);
15270 return -EOPNOTSUPP;
15271 }
15272#endif
15273 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015274 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015275 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015276 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015277 "%s: Not scanning on device_mode = %s (%d)",
15278 __func__, hdd_device_modetoString(pAdapter->device_mode),
15279 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 return -EOPNOTSUPP;
15281 }
15282
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015283 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15284 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15285 return -EOPNOTSUPP;
15286 }
15287
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 if (TRUE == pScanInfo->mScanPending)
15289 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015290 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15291 {
15292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15293 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015294 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015295 }
15296
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015297 // Don't allow scan if PNO scan is going on.
15298 if (pHddCtx->isPnoEnable)
15299 {
15300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15301 FL("pno scan in progress"));
15302 return -EBUSY;
15303 }
15304
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015305 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015306 //Channel and action frame is pending
15307 //Otherwise Cancel Remain On Channel and allow Scan
15308 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015309 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015310 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015311 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015312 return -EBUSY;
15313 }
15314
Jeff Johnson295189b2012-06-20 16:38:30 -070015315 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15316 {
15317 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015318 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015319 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015320 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015321 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15322 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015323 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015324 "%s: MAX TM Level Scan not allowed", __func__);
15325 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015326 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015327 }
15328 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15329
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015330 /* Check if scan is allowed at this point of time.
15331 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015332 if (TRUE == pHddCtx->btCoexModeSet)
15333 {
15334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15335 FL("BTCoex Mode operation in progress"));
15336 return -EBUSY;
15337 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015338 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015339 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015340
15341 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15342 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15343 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015344 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15345 pHddCtx->last_scan_reject_reason != curr_reason ||
15346 !pHddCtx->last_scan_reject_timestamp)
15347 {
15348 pHddCtx->last_scan_reject_session_id = curr_session_id;
15349 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015350 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015351 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015352 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015353 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015354 else
15355 {
15356 pHddCtx->scan_reject_cnt++;
15357
Abhishek Singhe4b12562017-06-20 16:53:39 +053015358 if ((pHddCtx->scan_reject_cnt >=
15359 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015360 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015361 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015362 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015363 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015364 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015365 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015366 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015367 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015368 if (pHddCtx->cfg_ini->enableFatalEvent)
15369 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15370 WLAN_LOG_INDICATOR_HOST_DRIVER,
15371 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15372 FALSE, FALSE);
15373 else
15374 {
15375 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015376 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015377 }
15378 }
15379 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015380 return -EBUSY;
15381 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015382 pHddCtx->last_scan_reject_timestamp = 0;
15383 pHddCtx->last_scan_reject_session_id = 0xFF;
15384 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015385 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015386
Jeff Johnson295189b2012-06-20 16:38:30 -070015387 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15388
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015389 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15390 * Becasue of this, driver is assuming that this is not wildcard scan and so
15391 * is not aging out the scan results.
15392 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015393 if ((request->ssids) && (request->n_ssids == 1) &&
15394 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015395 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015396 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015397
15398 if ((request->ssids) && (0 < request->n_ssids))
15399 {
15400 tCsrSSIDInfo *SsidInfo;
15401 int j;
15402 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15403 /* Allocate num_ssid tCsrSSIDInfo structure */
15404 SsidInfo = scanRequest.SSIDs.SSIDList =
15405 ( tCsrSSIDInfo *)vos_mem_malloc(
15406 request->n_ssids*sizeof(tCsrSSIDInfo));
15407
15408 if(NULL == scanRequest.SSIDs.SSIDList)
15409 {
15410 hddLog(VOS_TRACE_LEVEL_ERROR,
15411 "%s: memory alloc failed SSIDInfo buffer", __func__);
15412 return -ENOMEM;
15413 }
15414
15415 /* copy all the ssid's and their length */
15416 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15417 {
15418 /* get the ssid length */
15419 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15420 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15421 SsidInfo->SSID.length);
15422 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15423 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15424 j, SsidInfo->SSID.ssId);
15425 }
15426 /* set the scan type to active */
15427 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15428 }
15429 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015430 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015431 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15432 TRACE_CODE_HDD_CFG80211_SCAN,
15433 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015434 /* set the scan type to active */
15435 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015437 else
15438 {
15439 /*Set the scan type to default type, in this case it is ACTIVE*/
15440 scanRequest.scanType = pScanInfo->scan_mode;
15441 }
15442 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15443 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015444
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015445 csr_scan_request_assign_bssid(&scanRequest, request);
15446
Jeff Johnson295189b2012-06-20 16:38:30 -070015447 /* set BSSType to default type */
15448 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15449
15450 /*TODO: scan the requested channels only*/
15451
15452 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015453 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015454 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015455 hddLog(VOS_TRACE_LEVEL_WARN,
15456 "No of Scan Channels exceeded limit: %d", request->n_channels);
15457 request->n_channels = MAX_CHANNEL;
15458 }
15459
15460 hddLog(VOS_TRACE_LEVEL_INFO,
15461 "No of Scan Channels: %d", request->n_channels);
15462
15463
15464 if( request->n_channels )
15465 {
15466 char chList [(request->n_channels*5)+1];
15467 int len;
15468 channelList = vos_mem_malloc( request->n_channels );
15469 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015470 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015471 hddLog(VOS_TRACE_LEVEL_ERROR,
15472 "%s: memory alloc failed channelList", __func__);
15473 status = -ENOMEM;
15474 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015475 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015476
15477 for( i = 0, len = 0; i < request->n_channels ; i++ )
15478 {
15479 channelList[i] = request->channels[i]->hw_value;
15480 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15481 }
15482
Nirav Shah20ac06f2013-12-12 18:14:06 +053015483 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015484 "Channel-List: %s ", chList);
15485 }
c_hpothu53512302014-04-15 18:49:53 +053015486
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015487 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15488 scanRequest.ChannelInfo.ChannelList = channelList;
15489
15490 /* set requestType to full scan */
15491 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15492
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015493 /* if there is back to back scan happening in driver with in
15494 * nDeferScanTimeInterval interval driver should defer new scan request
15495 * and should provide last cached scan results instead of new channel list.
15496 * This rule is not applicable if scan is p2p scan.
15497 * This condition will work only in case when last request no of channels
15498 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015499 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015500 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015501 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015502
Sushant Kaushik86592172015-04-27 16:35:03 +053015503 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15504 /* if wps ie is NULL , then only defer scan */
15505 if ( pWpsIe == NULL &&
15506 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015507 {
15508 if ( pScanInfo->last_scan_timestamp !=0 &&
15509 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15510 {
15511 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15512 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15513 vos_mem_compare(pScanInfo->last_scan_channelList,
15514 channelList, pScanInfo->last_scan_numChannels))
15515 {
15516 hddLog(VOS_TRACE_LEVEL_WARN,
15517 " New and old station scan time differ is less then %u",
15518 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15519
15520 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015521 pAdapter);
15522
Agarwal Ashish57e84372014-12-05 18:26:53 +053015523 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015524 "Return old cached scan as all channels and no of channels are same");
15525
Agarwal Ashish57e84372014-12-05 18:26:53 +053015526 if (0 > ret)
15527 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015528
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015529 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015530
15531 status = eHAL_STATUS_SUCCESS;
15532 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015533 }
15534 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015535 }
15536
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015537 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15538 * search (Flush on both full scan and social scan but not on single
15539 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15540 */
15541
15542 /* Supplicant does single channel scan after 8-way handshake
15543 * and in that case driver shoudnt flush scan results. If
15544 * driver flushes the scan results here and unfortunately if
15545 * the AP doesnt respond to our probe req then association
15546 * fails which is not desired
15547 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015548 if ((request->n_ssids == 1)
15549 && (request->ssids != NULL)
15550 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15551 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015552
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015553 if( is_p2p_scan ||
15554 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015555 {
15556 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15557 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15558 pAdapter->sessionId );
15559 }
15560
15561 if( request->ie_len )
15562 {
15563 /* save this for future association (join requires this) */
15564 /*TODO: Array needs to be converted to dynamic allocation,
15565 * as multiple ie.s can be sent in cfg80211_scan_request structure
15566 * CR 597966
15567 */
15568 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15569 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15570 pScanInfo->scanAddIE.length = request->ie_len;
15571
15572 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15573 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15574 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015575 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015576 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015577 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015578 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15579 memcpy( pwextBuf->roamProfile.addIEScan,
15580 request->ie, request->ie_len);
15581 }
15582 else
15583 {
15584 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15585 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015586 }
15587
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015588 }
15589 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15590 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15591
15592 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15593 request->ie_len);
15594 if (pP2pIe != NULL)
15595 {
15596#ifdef WLAN_FEATURE_P2P_DEBUG
15597 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15598 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15599 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015600 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015601 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15602 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15603 "Go nego completed to Connection is started");
15604 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15605 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015606 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015607 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15608 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015609 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015610 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15611 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15612 "Disconnected state to Connection is started");
15613 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15614 "for 4way Handshake");
15615 }
15616#endif
15617
15618 /* no_cck will be set during p2p find to disable 11b rates */
15619 if(TRUE == request->no_cck)
15620 {
15621 hddLog(VOS_TRACE_LEVEL_INFO,
15622 "%s: This is a P2P Search", __func__);
15623 scanRequest.p2pSearch = 1;
15624
15625 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015626 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015627 /* set requestType to P2P Discovery */
15628 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15629 }
15630
15631 /*
15632 Skip Dfs Channel in case of P2P Search
15633 if it is set in ini file
15634 */
15635 if(cfg_param->skipDfsChnlInP2pSearch)
15636 {
15637 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015638 }
15639 else
15640 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015641 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015642 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015643
Agarwal Ashish4f616132013-12-30 23:32:50 +053015644 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 }
15646 }
15647
15648 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15649
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015650#ifdef FEATURE_WLAN_TDLS
15651 /* if tdls disagree scan right now, return immediately.
15652 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15653 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15654 */
15655 status = wlan_hdd_tdls_scan_callback (pAdapter,
15656 wiphy,
15657#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15658 dev,
15659#endif
15660 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015661 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015662 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015663 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15665 "scan rejected %d", __func__, status);
15666 else
15667 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15668 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015669 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015670 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015671 }
15672#endif
15673
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015674 /* acquire the wakelock to avoid the apps suspend during the scan. To
15675 * address the following issues.
15676 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15677 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15678 * for long time, this result in apps running at full power for long time.
15679 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15680 * be stuck in full power because of resume BMPS
15681 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015682 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015683
Nirav Shah20ac06f2013-12-12 18:14:06 +053015684 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15685 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015686 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15687 scanRequest.requestType, scanRequest.scanType,
15688 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015689 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15690
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015691 if (pHddCtx->spoofMacAddr.isEnabled &&
15692 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015693 {
15694 hddLog(VOS_TRACE_LEVEL_INFO,
15695 "%s: MAC Spoofing enabled for current scan", __func__);
15696 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15697 * to fill TxBds for probe request during current scan
15698 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015699 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015700 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015701
15702 if(status != VOS_STATUS_SUCCESS)
15703 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015704 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015705 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015706#ifdef FEATURE_WLAN_TDLS
15707 wlan_hdd_tdls_scan_done_callback(pAdapter);
15708#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015709 goto free_mem;
15710 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015711 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015712 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015713 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015714 pAdapter->sessionId, &scanRequest, &scanId,
15715 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015716
Jeff Johnson295189b2012-06-20 16:38:30 -070015717 if (eHAL_STATUS_SUCCESS != status)
15718 {
15719 hddLog(VOS_TRACE_LEVEL_ERROR,
15720 "%s: sme_ScanRequest returned error %d", __func__, status);
15721 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015722 if(eHAL_STATUS_RESOURCES == status)
15723 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15725 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015726 status = -EBUSY;
15727 } else {
15728 status = -EIO;
15729 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015730 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015731
15732#ifdef FEATURE_WLAN_TDLS
15733 wlan_hdd_tdls_scan_done_callback(pAdapter);
15734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015735 goto free_mem;
15736 }
15737
15738 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015739 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015740 pAdapter->request = request;
15741 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015742 pScanInfo->no_cck = request->no_cck;
15743 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15744 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15745 pHddCtx->scan_info.last_scan_channelList[i] =
15746 request->channels[i]->hw_value;
15747 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015748
15749 complete(&pScanInfo->scan_req_completion_event);
15750
15751free_mem:
15752 if( scanRequest.SSIDs.SSIDList )
15753 {
15754 vos_mem_free(scanRequest.SSIDs.SSIDList);
15755 }
15756
15757 if( channelList )
15758 vos_mem_free( channelList );
15759
15760 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015761 return status;
15762}
15763
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015764int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15765#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15766 struct net_device *dev,
15767#endif
15768 struct cfg80211_scan_request *request)
15769{
15770 int ret;
15771
15772 vos_ssr_protect(__func__);
15773 ret = __wlan_hdd_cfg80211_scan(wiphy,
15774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15775 dev,
15776#endif
15777 request);
15778 vos_ssr_unprotect(__func__);
15779
15780 return ret;
15781}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015782
15783void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15784{
15785 v_U8_t iniDot11Mode =
15786 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15787 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15788
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015789 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15790 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015791 switch ( iniDot11Mode )
15792 {
15793 case eHDD_DOT11_MODE_AUTO:
15794 case eHDD_DOT11_MODE_11ac:
15795 case eHDD_DOT11_MODE_11ac_ONLY:
15796#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015797 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15798 sme_IsFeatureSupportedByFW(DOT11AC) )
15799 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15800 else
15801 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015802#else
15803 hddDot11Mode = eHDD_DOT11_MODE_11n;
15804#endif
15805 break;
15806 case eHDD_DOT11_MODE_11n:
15807 case eHDD_DOT11_MODE_11n_ONLY:
15808 hddDot11Mode = eHDD_DOT11_MODE_11n;
15809 break;
15810 default:
15811 hddDot11Mode = iniDot11Mode;
15812 break;
15813 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015814#ifdef WLAN_FEATURE_AP_HT40_24G
15815 if (operationChannel > SIR_11B_CHANNEL_END)
15816#endif
15817 {
15818 /* This call decides required channel bonding mode */
15819 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015820 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015821 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015822 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015823}
15824
Jeff Johnson295189b2012-06-20 16:38:30 -070015825/*
15826 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015827 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015828 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015829int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015830 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15831 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015832{
15833 int status = 0;
15834 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015835 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015836 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015837 v_U32_t roamId;
15838 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015839 eCsrAuthType RSNAuthType;
15840
15841 ENTER();
15842
15843 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015844 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015845 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015846
15847 status = wlan_hdd_validate_context(pHddCtx);
15848 if (status)
15849 {
Yue Mae36e3552014-03-05 17:06:20 -080015850 return status;
15851 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015852
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15854 {
15855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15856 return -EINVAL;
15857 }
15858
Nitesh Shah9b066282017-06-06 18:05:52 +053015859
Jeff Johnson295189b2012-06-20 16:38:30 -070015860 pRoamProfile = &pWextState->roamProfile;
15861
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015862 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015863 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015864 hdd_station_ctx_t *pHddStaCtx;
15865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015866 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015867
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015868 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15869
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015870 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015871 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15872 {
15873 /*QoS not enabled in cfg file*/
15874 pRoamProfile->uapsd_mask = 0;
15875 }
15876 else
15877 {
15878 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15881 }
15882
15883 pRoamProfile->SSIDs.numOfSSIDs = 1;
15884 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15885 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015886 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015887 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15888 ssid, ssid_len);
15889
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015890 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15891 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15892
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 if (bssid)
15894 {
15895 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015896 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015897 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015898 /* Save BSSID in seperate variable as well, as RoamProfile
15899 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015900 case of join failure we should send valid BSSID to supplicant
15901 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015902 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015904
Jeff Johnson295189b2012-06-20 16:38:30 -070015905 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015906 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015907 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015908 /* Store bssid_hint to use in the scan filter. */
15909 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15910 WNI_CFG_BSSID_LEN);
15911 /*
15912 * Save BSSID in seperate variable as well, as RoamProfile
15913 * BSSID is getting zeroed out in the association process. And in
15914 * case of join failure we should send valid BSSID to supplicant
15915 */
15916 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15917 WNI_CFG_BSSID_LEN);
15918 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15919 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015920 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015921
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015922
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015923 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15924 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15926 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015927 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015928 /*set gen ie*/
15929 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15930 /*set auth*/
15931 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15932 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015933#ifdef FEATURE_WLAN_WAPI
15934 if (pAdapter->wapi_info.nWapiMode)
15935 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015936 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015937 switch (pAdapter->wapi_info.wapiAuthMode)
15938 {
15939 case WAPI_AUTH_MODE_PSK:
15940 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015941 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 pAdapter->wapi_info.wapiAuthMode);
15943 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15944 break;
15945 }
15946 case WAPI_AUTH_MODE_CERT:
15947 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015948 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015949 pAdapter->wapi_info.wapiAuthMode);
15950 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15951 break;
15952 }
15953 } // End of switch
15954 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15955 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15956 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015957 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015958 pRoamProfile->AuthType.numEntries = 1;
15959 pRoamProfile->EncryptionType.numEntries = 1;
15960 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15961 pRoamProfile->mcEncryptionType.numEntries = 1;
15962 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15963 }
15964 }
15965#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015966#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015967 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015968 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15969 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15970 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015971 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15972 sizeof (tSirGtkOffloadParams));
15973 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015974 }
15975#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015976 pRoamProfile->csrPersona = pAdapter->device_mode;
15977
Jeff Johnson32d95a32012-09-10 13:15:23 -070015978 if( operatingChannel )
15979 {
15980 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15981 pRoamProfile->ChannelInfo.numOfChannels = 1;
15982 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015983 else
15984 {
15985 pRoamProfile->ChannelInfo.ChannelList = NULL;
15986 pRoamProfile->ChannelInfo.numOfChannels = 0;
15987 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015988 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15989 {
15990 hdd_select_cbmode(pAdapter,operatingChannel);
15991 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015992
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015993 /*
15994 * Change conn_state to connecting before sme_RoamConnect(),
15995 * because sme_RoamConnect() has a direct path to call
15996 * hdd_smeRoamCallback(), which will change the conn_state
15997 * If direct path, conn_state will be accordingly changed
15998 * to NotConnected or Associated by either
15999 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16000 * in sme_RoamCallback()
16001 * if sme_RomConnect is to be queued,
16002 * Connecting state will remain until it is completed.
16003 * If connection state is not changed,
16004 * connection state will remain in eConnectionState_NotConnected state.
16005 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16006 * if conn state is eConnectionState_NotConnected.
16007 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16008 * informed of connect result indication which is an issue.
16009 */
16010
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016011 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16012 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016013 {
16014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016015 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016016 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16017 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016018 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16019 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016020 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016021
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016022 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 pAdapter->sessionId, pRoamProfile, &roamId);
16024
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016025 if ((eHAL_STATUS_SUCCESS != status) &&
16026 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16027 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016028
16029 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016030 hddLog(VOS_TRACE_LEVEL_ERROR,
16031 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16032 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016033 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016034 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016035 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016036 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016037
16038 pRoamProfile->ChannelInfo.ChannelList = NULL;
16039 pRoamProfile->ChannelInfo.numOfChannels = 0;
16040
Jeff Johnson295189b2012-06-20 16:38:30 -070016041 }
16042 else
16043 {
16044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16045 return -EINVAL;
16046 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016047 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016048 return status;
16049}
16050
16051/*
16052 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16053 * This function is used to set the authentication type (OPEN/SHARED).
16054 *
16055 */
16056static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16057 enum nl80211_auth_type auth_type)
16058{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016059 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16061
16062 ENTER();
16063
16064 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016065 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016066 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016067 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016068 hddLog(VOS_TRACE_LEVEL_INFO,
16069 "%s: set authentication type to AUTOSWITCH", __func__);
16070 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16071 break;
16072
16073 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016074#ifdef WLAN_FEATURE_VOWIFI_11R
16075 case NL80211_AUTHTYPE_FT:
16076#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016077 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016078 "%s: set authentication type to OPEN", __func__);
16079 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16080 break;
16081
16082 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016083 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016084 "%s: set authentication type to SHARED", __func__);
16085 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16086 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016087#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016089 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016090 "%s: set authentication type to CCKM WPA", __func__);
16091 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16092 break;
16093#endif
16094
16095
16096 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016097 hddLog(VOS_TRACE_LEVEL_ERROR,
16098 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016099 auth_type);
16100 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16101 return -EINVAL;
16102 }
16103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016104 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 pHddStaCtx->conn_info.authType;
16106 return 0;
16107}
16108
16109/*
16110 * FUNCTION: wlan_hdd_set_akm_suite
16111 * This function is used to set the key mgmt type(PSK/8021x).
16112 *
16113 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016114static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016115 u32 key_mgmt
16116 )
16117{
16118 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16119 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016120 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016121#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016122#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016123#endif
16124#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016125#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016126#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016127 /*set key mgmt type*/
16128 switch(key_mgmt)
16129 {
16130 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016131 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016132#ifdef WLAN_FEATURE_VOWIFI_11R
16133 case WLAN_AKM_SUITE_FT_PSK:
16134#endif
16135 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016136 __func__);
16137 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16138 break;
16139
16140 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016141 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016142#ifdef WLAN_FEATURE_VOWIFI_11R
16143 case WLAN_AKM_SUITE_FT_8021X:
16144#endif
16145 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016146 __func__);
16147 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16148 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016149#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016150#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16151#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16152 case WLAN_AKM_SUITE_CCKM:
16153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16154 __func__);
16155 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16156 break;
16157#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016158#ifndef WLAN_AKM_SUITE_OSEN
16159#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16160 case WLAN_AKM_SUITE_OSEN:
16161 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16162 __func__);
16163 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16164 break;
16165#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016166
16167 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016169 __func__, key_mgmt);
16170 return -EINVAL;
16171
16172 }
16173 return 0;
16174}
16175
16176/*
16177 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016178 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016179 * (NONE/WEP40/WEP104/TKIP/CCMP).
16180 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016181static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16182 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016183 bool ucast
16184 )
16185{
16186 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016187 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16189
16190 ENTER();
16191
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016192 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016194 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016195 __func__, cipher);
16196 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16197 }
16198 else
16199 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016200
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016202 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 {
16204 case IW_AUTH_CIPHER_NONE:
16205 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16206 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016207
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016209 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016211
Jeff Johnson295189b2012-06-20 16:38:30 -070016212 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016213 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016214 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016215
Jeff Johnson295189b2012-06-20 16:38:30 -070016216 case WLAN_CIPHER_SUITE_TKIP:
16217 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16218 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016219
Jeff Johnson295189b2012-06-20 16:38:30 -070016220 case WLAN_CIPHER_SUITE_CCMP:
16221 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16222 break;
16223#ifdef FEATURE_WLAN_WAPI
16224 case WLAN_CIPHER_SUITE_SMS4:
16225 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16226 break;
16227#endif
16228
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016229#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016230 case WLAN_CIPHER_SUITE_KRK:
16231 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16232 break;
16233#endif
16234 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016236 __func__, cipher);
16237 return -EOPNOTSUPP;
16238 }
16239 }
16240
16241 if (ucast)
16242 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016243 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016244 __func__, encryptionType);
16245 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16246 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016247 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016248 encryptionType;
16249 }
16250 else
16251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016253 __func__, encryptionType);
16254 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16255 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16256 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16257 }
16258
16259 return 0;
16260}
16261
16262
16263/*
16264 * FUNCTION: wlan_hdd_cfg80211_set_ie
16265 * This function is used to parse WPA/RSN IE's.
16266 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016267int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016268#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16269 const u8 *ie,
16270#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016271 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016272#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 size_t ie_len
16274 )
16275{
16276 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16278 const u8 *genie = ie;
16279#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016281#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016282 v_U16_t remLen = ie_len;
16283#ifdef FEATURE_WLAN_WAPI
16284 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16285 u16 *tmp;
16286 v_U16_t akmsuiteCount;
16287 int *akmlist;
16288#endif
16289 ENTER();
16290
16291 /* clear previous assocAddIE */
16292 pWextState->assocAddIE.length = 0;
16293 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016294 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016295
16296 while (remLen >= 2)
16297 {
16298 v_U16_t eLen = 0;
16299 v_U8_t elementId;
16300 elementId = *genie++;
16301 eLen = *genie++;
16302 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016303
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016304 /* Sanity check on eLen */
16305 if (eLen > remLen) {
16306 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16307 __func__, eLen, elementId);
16308 VOS_ASSERT(0);
16309 return -EINVAL;
16310 }
16311
Arif Hussain6d2a3322013-11-17 19:50:10 -080016312 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016313 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016314
16315 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016316 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016317 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016318 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 -070016319 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016320 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016321 "%s: Invalid WPA IE", __func__);
16322 return -EINVAL;
16323 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016324 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016325 {
16326 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016327 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016328 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016329
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016330 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016331 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016332 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16333 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 VOS_ASSERT(0);
16335 return -ENOMEM;
16336 }
16337 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16338 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16339 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016340
Jeff Johnson295189b2012-06-20 16:38:30 -070016341 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16342 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16343 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16344 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016345 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16346 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016347 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16348 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16349 __func__, eLen);
16350 VOS_ASSERT(0);
16351 return -EINVAL;
16352 }
16353
Jeff Johnson295189b2012-06-20 16:38:30 -070016354 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16355 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16356 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16357 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16358 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16359 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016360 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016361 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016362 {
16363 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016364 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016365 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016366
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016367 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016368 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016369 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16370 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016371 VOS_ASSERT(0);
16372 return -ENOMEM;
16373 }
16374 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16375 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16376 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016377
Jeff Johnson295189b2012-06-20 16:38:30 -070016378 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16379 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16380 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016381#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016382 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16383 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 /*Consider WFD IE, only for P2P Client */
16385 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16386 {
16387 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016388 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016390
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016391 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016392 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016393 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16394 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016395 VOS_ASSERT(0);
16396 return -ENOMEM;
16397 }
16398 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16399 // WPS IE + P2P IE + WFD IE
16400 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16401 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016402
Jeff Johnson295189b2012-06-20 16:38:30 -070016403 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16404 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16405 }
16406#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016407 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016408 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016409 HS20_OUI_TYPE_SIZE)) )
16410 {
16411 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016412 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016413 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016414
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016415 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016416 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016417 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16418 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016419 VOS_ASSERT(0);
16420 return -ENOMEM;
16421 }
16422 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16423 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016424
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016425 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16426 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16427 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016428 /* Appending OSEN Information Element in Assiciation Request */
16429 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16430 OSEN_OUI_TYPE_SIZE)) )
16431 {
16432 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16433 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16434 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016435
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016436 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016437 {
16438 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16439 "Need bigger buffer space");
16440 VOS_ASSERT(0);
16441 return -ENOMEM;
16442 }
16443 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16444 pWextState->assocAddIE.length += eLen + 2;
16445
16446 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16447 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16448 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16449 }
16450
Abhishek Singh4322e622015-06-10 15:42:54 +053016451 /* Update only for WPA IE */
16452 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16453 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016454
16455 /* populating as ADDIE in beacon frames */
16456 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016457 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016458 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16459 {
16460 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16461 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16462 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16463 {
16464 hddLog(LOGE,
16465 "Coldn't pass "
16466 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16467 }
16468 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16469 else
16470 hddLog(LOGE,
16471 "Could not pass on "
16472 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16473
16474 /* IBSS mode doesn't contain params->proberesp_ies still
16475 beaconIE's need to be populated in probe response frames */
16476 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16477 {
16478 u16 rem_probe_resp_ie_len = eLen + 2;
16479 u8 probe_rsp_ie_len[3] = {0};
16480 u8 counter = 0;
16481
16482 /* Check Probe Resp Length if it is greater then 255 then
16483 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16484 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16485 not able Store More then 255 bytes into One Variable */
16486
16487 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16488 {
16489 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16490 {
16491 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16492 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16493 }
16494 else
16495 {
16496 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16497 rem_probe_resp_ie_len = 0;
16498 }
16499 }
16500
16501 rem_probe_resp_ie_len = 0;
16502
16503 if (probe_rsp_ie_len[0] > 0)
16504 {
16505 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16506 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16507 (tANI_U8*)(genie - 2),
16508 probe_rsp_ie_len[0], NULL,
16509 eANI_BOOLEAN_FALSE)
16510 == eHAL_STATUS_FAILURE)
16511 {
16512 hddLog(LOGE,
16513 "Could not pass"
16514 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16515 }
16516 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16517 }
16518
16519 if (probe_rsp_ie_len[1] > 0)
16520 {
16521 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16522 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16523 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16524 probe_rsp_ie_len[1], NULL,
16525 eANI_BOOLEAN_FALSE)
16526 == eHAL_STATUS_FAILURE)
16527 {
16528 hddLog(LOGE,
16529 "Could not pass"
16530 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16531 }
16532 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16533 }
16534
16535 if (probe_rsp_ie_len[2] > 0)
16536 {
16537 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16538 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16539 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16540 probe_rsp_ie_len[2], NULL,
16541 eANI_BOOLEAN_FALSE)
16542 == eHAL_STATUS_FAILURE)
16543 {
16544 hddLog(LOGE,
16545 "Could not pass"
16546 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16547 }
16548 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16549 }
16550
16551 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16552 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16553 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16554 {
16555 hddLog(LOGE,
16556 "Could not pass"
16557 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16558 }
16559 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016560 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016561 break;
16562 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016563 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16564 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16565 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16566 VOS_ASSERT(0);
16567 return -EINVAL;
16568 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016569 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16570 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16571 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16572 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16573 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16574 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016575
Abhishek Singhb16f3562016-01-20 11:08:32 +053016576 /* Appending extended capabilities with Interworking or
16577 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016578 *
16579 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016580 * interworkingService or bsstransition bit is set to 1.
16581 * Driver is only interested in interworkingService and
16582 * bsstransition capability from supplicant.
16583 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016584 * required from supplicat, it needs to be handled while
16585 * sending Assoc Req in LIM.
16586 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016587 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016588 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016589 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016590 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016591 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016592
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016593 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016594 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016595 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16596 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016597 VOS_ASSERT(0);
16598 return -ENOMEM;
16599 }
16600 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16601 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016602
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016603 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16604 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16605 break;
16606 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016607#ifdef FEATURE_WLAN_WAPI
16608 case WLAN_EID_WAPI:
16609 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016610 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016611 pAdapter->wapi_info.nWapiMode);
16612 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016613 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016614 akmsuiteCount = WPA_GET_LE16(tmp);
16615 tmp = tmp + 1;
16616 akmlist = (int *)(tmp);
16617 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16618 {
16619 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16620 }
16621 else
16622 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016623 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016624 VOS_ASSERT(0);
16625 return -EINVAL;
16626 }
16627
16628 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16629 {
16630 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016631 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016632 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016633 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016634 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016635 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016636 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016637 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016638 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16639 }
16640 break;
16641#endif
16642 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016643 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016644 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016645 /* when Unknown IE is received we should break and continue
16646 * to the next IE in the buffer instead we were returning
16647 * so changing this to break */
16648 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016649 }
16650 genie += eLen;
16651 remLen -= eLen;
16652 }
16653 EXIT();
16654 return 0;
16655}
16656
16657/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016658 * FUNCTION: hdd_isWPAIEPresent
16659 * Parse the received IE to find the WPA IE
16660 *
16661 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016662static bool hdd_isWPAIEPresent(
16663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16664 const u8 *ie,
16665#else
16666 u8 *ie,
16667#endif
16668 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016669{
16670 v_U8_t eLen = 0;
16671 v_U16_t remLen = ie_len;
16672 v_U8_t elementId = 0;
16673
16674 while (remLen >= 2)
16675 {
16676 elementId = *ie++;
16677 eLen = *ie++;
16678 remLen -= 2;
16679 if (eLen > remLen)
16680 {
16681 hddLog(VOS_TRACE_LEVEL_ERROR,
16682 "%s: IE length is wrong %d", __func__, eLen);
16683 return FALSE;
16684 }
16685 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16686 {
16687 /* OUI - 0x00 0X50 0XF2
16688 WPA Information Element - 0x01
16689 WPA version - 0x01*/
16690 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16691 return TRUE;
16692 }
16693 ie += eLen;
16694 remLen -= eLen;
16695 }
16696 return FALSE;
16697}
16698
16699/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016700 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016701 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016702 * parameters during connect operation.
16703 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016704int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016705 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016706 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016707{
16708 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016709 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016710 ENTER();
16711
16712 /*set wpa version*/
16713 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16714
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016715 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016716 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016717 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016718 {
16719 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16720 }
16721 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16722 {
16723 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16724 }
16725 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016726
16727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016728 pWextState->wpaVersion);
16729
16730 /*set authentication type*/
16731 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16732
16733 if (0 > status)
16734 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016735 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016736 "%s: failed to set authentication type ", __func__);
16737 return status;
16738 }
16739
16740 /*set key mgmt type*/
16741 if (req->crypto.n_akm_suites)
16742 {
16743 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16744 if (0 > status)
16745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016747 __func__);
16748 return status;
16749 }
16750 }
16751
16752 /*set pairwise cipher type*/
16753 if (req->crypto.n_ciphers_pairwise)
16754 {
16755 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16756 req->crypto.ciphers_pairwise[0], true);
16757 if (0 > status)
16758 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016759 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016760 "%s: failed to set unicast cipher type", __func__);
16761 return status;
16762 }
16763 }
16764 else
16765 {
16766 /*Reset previous cipher suite to none*/
16767 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16768 if (0 > status)
16769 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016770 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016771 "%s: failed to set unicast cipher type", __func__);
16772 return status;
16773 }
16774 }
16775
16776 /*set group cipher type*/
16777 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16778 false);
16779
16780 if (0 > status)
16781 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016782 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016783 __func__);
16784 return status;
16785 }
16786
Chet Lanctot186b5732013-03-18 10:26:30 -070016787#ifdef WLAN_FEATURE_11W
16788 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16789#endif
16790
Jeff Johnson295189b2012-06-20 16:38:30 -070016791 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16792 if (req->ie_len)
16793 {
16794 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16795 if ( 0 > status)
16796 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016798 __func__);
16799 return status;
16800 }
16801 }
16802
16803 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016804 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016805 {
16806 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16807 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16808 )
16809 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016810 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016811 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16812 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016814 __func__);
16815 return -EOPNOTSUPP;
16816 }
16817 else
16818 {
16819 u8 key_len = req->key_len;
16820 u8 key_idx = req->key_idx;
16821
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016822 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016823 && (CSR_MAX_NUM_KEY > key_idx)
16824 )
16825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016826 hddLog(VOS_TRACE_LEVEL_INFO,
16827 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016828 __func__, key_idx, key_len);
16829 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016830 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016831 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016832 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 (u8)key_len;
16834 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16835 }
16836 }
16837 }
16838 }
16839
16840 return status;
16841}
16842
16843/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016844 * FUNCTION: wlan_hdd_try_disconnect
16845 * This function is used to disconnect from previous
16846 * connection
16847 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016848int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016849{
16850 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016851 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016852 hdd_station_ctx_t *pHddStaCtx;
16853 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016854 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016855
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016856 ret = wlan_hdd_validate_context(pHddCtx);
16857 if (0 != ret)
16858 {
16859 return ret;
16860 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016861 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16862
16863 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16864
16865 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16866 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016867 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016868 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16869 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016870 /* Indicate disconnect to SME so that in-progress connection or preauth
16871 * can be aborted
16872 */
16873 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16874 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016875 spin_lock_bh(&pAdapter->lock_for_active_session);
16876 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16877 {
16878 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16879 }
16880 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016881 hdd_connSetConnectionState(pHddStaCtx,
16882 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016883 /* Issue disconnect to CSR */
16884 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016885 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016886 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016887 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16888 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16889 hddLog(LOG1,
16890 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16891 } else if ( 0 != status ) {
16892 hddLog(LOGE,
16893 FL("csrRoamDisconnect failure, returned %d"),
16894 (int)status );
16895 result = -EINVAL;
16896 goto disconnected;
16897 }
16898 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016899 &pAdapter->disconnect_comp_var,
16900 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016901 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16902 hddLog(LOGE,
16903 "%s: Failed to disconnect, timed out", __func__);
16904 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016905 }
16906 }
16907 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16908 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016909 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016910 &pAdapter->disconnect_comp_var,
16911 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016912 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016913 {
16914 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016915 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016916 }
16917 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016918disconnected:
16919 hddLog(LOG1,
16920 FL("Set HDD connState to eConnectionState_NotConnected"));
16921 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16922 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016923}
16924
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016925/**
16926 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16927 * @adapter: Pointer to the HDD adapter
16928 * @req: Pointer to the structure cfg_connect_params receieved from user space
16929 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053016930 * This function will start reassociation if prev_bssid is set and bssid/
16931 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016932 *
16933 * Return: success if reassociation is happening
16934 * Error code if reassociation is not permitted or not happening
16935 */
16936#ifdef CFG80211_CONNECT_PREV_BSSID
16937static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16938 struct cfg80211_connect_params *req)
16939{
16940 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053016941 const uint8_t *bssid = NULL;
16942 uint16_t channel = 0;
16943
16944 if (req->bssid)
16945 bssid = req->bssid;
16946 else if (req->bssid_hint)
16947 bssid = req->bssid_hint;
16948
16949 if (req->channel)
16950 channel = req->channel->hw_value;
16951 else if (req->channel_hint)
16952 channel = req->channel_hint->hw_value;
16953
16954 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016955 hddLog(VOS_TRACE_LEVEL_INFO,
16956 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053016957 channel, MAC_ADDR_ARRAY(bssid));
16958 status = hdd_reassoc(adapter, bssid, channel,
16959 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016960 }
16961 return status;
16962}
16963#else
16964static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16965 struct cfg80211_connect_params *req)
16966{
16967 return -EPERM;
16968}
16969#endif
16970
Abhishek Singhe3beee22017-07-31 15:35:40 +053016971/**
16972 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16973 * connect in HT20 mode
16974 * @hdd_ctx: hdd context
16975 * @adapter: Pointer to the HDD adapter
16976 * @req: Pointer to the structure cfg_connect_params receieved from user space
16977 *
16978 * This function will check if supplicant has indicated to to connect in HT20
16979 * mode. this is currently applicable only for 2.4Ghz mode only.
16980 * if feature is enabled and supplicant indicate HT20 set
16981 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16982 *
16983 * Return: void
16984 */
16985#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16986static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16987 hdd_adapter_t *adapter,
16988 struct cfg80211_connect_params *req)
16989{
16990 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16991 tCsrRoamProfile *roam_profile;
16992
16993 roam_profile = &wext_state->roamProfile;
16994 roam_profile->force_24ghz_in_ht20 = false;
16995 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16996 !(req->ht_capa.cap_info &
16997 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16998 roam_profile->force_24ghz_in_ht20 = true;
16999
17000 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17001 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17002}
17003#else
17004static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17005 hdd_adapter_t *adapter,
17006 struct cfg80211_connect_params *req)
17007{
17008 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17009 tCsrRoamProfile *roam_profile;
17010
17011 roam_profile = &wext_state->roamProfile;
17012 roam_profile->force_24ghz_in_ht20 = false;
17013}
17014#endif
17015
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017016/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017017 * FUNCTION: __wlan_hdd_cfg80211_connect
17018 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017020static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017021 struct net_device *ndev,
17022 struct cfg80211_connect_params *req
17023 )
17024{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017025 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017026 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17028 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017029 const u8 *bssid_hint = req->bssid_hint;
17030#else
17031 const u8 *bssid_hint = NULL;
17032#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017034 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017035 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017036
17037 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017038
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017039 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17040 TRACE_CODE_HDD_CFG80211_CONNECT,
17041 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017042 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017043 "%s: device_mode = %s (%d)", __func__,
17044 hdd_device_modetoString(pAdapter->device_mode),
17045 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017046
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017047 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017048 if (!pHddCtx)
17049 {
17050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17051 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017052 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017053 }
17054
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017055 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017056 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017057 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017058 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017059 }
17060
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017061 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17062 return -EINVAL;
17063
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017064 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17065 if (0 == status)
17066 return status;
17067
Agarwal Ashish51325b52014-06-16 16:50:49 +053017068
Jeff Johnson295189b2012-06-20 16:38:30 -070017069#ifdef WLAN_BTAMP_FEATURE
17070 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017071 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017072 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017073 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017074 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017075 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 }
17077#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017078
17079 //If Device Mode is Station Concurrent Sessions Exit BMps
17080 //P2P Mode will be taken care in Open/close adapter
17081 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017082 (vos_concurrent_open_sessions_running())) {
17083 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17084 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017085 }
17086
17087 /*Try disconnecting if already in connected state*/
17088 status = wlan_hdd_try_disconnect(pAdapter);
17089 if ( 0 > status)
17090 {
17091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17092 " connection"));
17093 return -EALREADY;
17094 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017095 /* Check for max concurrent connections after doing disconnect if any*/
17096 if (vos_max_concurrent_connections_reached()) {
17097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17098 return -ECONNREFUSED;
17099 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017100
Jeff Johnson295189b2012-06-20 16:38:30 -070017101 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017102 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017103
17104 if ( 0 > status)
17105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017107 __func__);
17108 return status;
17109 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017110
17111 if (pHddCtx->spoofMacAddr.isEnabled)
17112 {
17113 hddLog(VOS_TRACE_LEVEL_INFO,
17114 "%s: MAC Spoofing enabled ", __func__);
17115 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17116 * to fill TxBds for probe request during SSID scan which may happen
17117 * as part of connect command
17118 */
17119 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17120 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17121 if (status != VOS_STATUS_SUCCESS)
17122 return -ECONNREFUSED;
17123 }
17124
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017125 if (req->channel)
17126 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017127 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017128 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017129
17130 /* Abort if any scan is going on */
17131 status = wlan_hdd_scan_abort(pAdapter);
17132 if (0 != status)
17133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17134
Abhishek Singhe3beee22017-07-31 15:35:40 +053017135 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17136
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017137 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17138 req->ssid_len, req->bssid,
17139 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017140
Sushant Kaushikd7083982015-03-18 14:33:24 +053017141 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017142 {
17143 //ReEnable BMPS if disabled
17144 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17145 (NULL != pHddCtx))
17146 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017147 if (pHddCtx->hdd_wlan_suspended)
17148 {
17149 hdd_set_pwrparams(pHddCtx);
17150 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017151 //ReEnable Bmps and Imps back
17152 hdd_enable_bmps_imps(pHddCtx);
17153 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017155 return status;
17156 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017157 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017158 EXIT();
17159 return status;
17160}
17161
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017162static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17163 struct net_device *ndev,
17164 struct cfg80211_connect_params *req)
17165{
17166 int ret;
17167 vos_ssr_protect(__func__);
17168 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17169 vos_ssr_unprotect(__func__);
17170
17171 return ret;
17172}
Jeff Johnson295189b2012-06-20 16:38:30 -070017173
17174/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017175 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017176 * This function is used to issue a disconnect request to SME
17177 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017178static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017179 struct net_device *dev,
17180 u16 reason
17181 )
17182{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017184 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017185 tCsrRoamProfile *pRoamProfile;
17186 hdd_station_ctx_t *pHddStaCtx;
17187 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017188#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017189 tANI_U8 staIdx;
17190#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017191
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017193
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017194 if (!pAdapter) {
17195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17196 return -EINVAL;
17197 }
17198
17199 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17200 if (!pHddStaCtx) {
17201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17202 return -EINVAL;
17203 }
17204
17205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17206 status = wlan_hdd_validate_context(pHddCtx);
17207 if (0 != status)
17208 {
17209 return status;
17210 }
17211
17212 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17213
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17215 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17216 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017217 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17218 __func__, hdd_device_modetoString(pAdapter->device_mode),
17219 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017220
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017221 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17222 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017223
Jeff Johnson295189b2012-06-20 16:38:30 -070017224 if (NULL != pRoamProfile)
17225 {
17226 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017227 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17228 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017230 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017231 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017232 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017233 switch(reason)
17234 {
17235 case WLAN_REASON_MIC_FAILURE:
17236 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17237 break;
17238
17239 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17240 case WLAN_REASON_DISASSOC_AP_BUSY:
17241 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17242 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17243 break;
17244
17245 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17246 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017247 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017248 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17249 break;
17250
Jeff Johnson295189b2012-06-20 16:38:30 -070017251 default:
17252 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17253 break;
17254 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017255 pScanInfo = &pHddCtx->scan_info;
17256 if (pScanInfo->mScanPending)
17257 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017258 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017259 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017260 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017261 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017262 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017263 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017264#ifdef FEATURE_WLAN_TDLS
17265 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017266 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017267 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017268 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17269 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017270 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017271 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017272 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017274 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017275 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017276 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017277 status = sme_DeleteTdlsPeerSta(
17278 WLAN_HDD_GET_HAL_CTX(pAdapter),
17279 pAdapter->sessionId,
17280 mac);
17281 if (status != eHAL_STATUS_SUCCESS) {
17282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17283 return -EPERM;
17284 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017285 }
17286 }
17287#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017288
17289 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17290 reasonCode,
17291 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017292 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17293 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017294 {
17295 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017296 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017297 __func__, (int)status );
17298 return -EINVAL;
17299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017300 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017301 else
17302 {
17303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17304 "called while in %d state", __func__,
17305 pHddStaCtx->conn_info.connState);
17306 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017307 }
17308 else
17309 {
17310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17311 }
17312
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017313 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017314 return status;
17315}
17316
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017317static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17318 struct net_device *dev,
17319 u16 reason
17320 )
17321{
17322 int ret;
17323 vos_ssr_protect(__func__);
17324 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17325 vos_ssr_unprotect(__func__);
17326
17327 return ret;
17328}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017329
Jeff Johnson295189b2012-06-20 16:38:30 -070017330/*
17331 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017332 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017333 * settings in IBSS mode.
17334 */
17335static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017336 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017337 struct cfg80211_ibss_params *params
17338 )
17339{
17340 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017341 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017342 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017343 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17344 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017345
Jeff Johnson295189b2012-06-20 16:38:30 -070017346 ENTER();
17347
17348 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017349 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017350
17351 if (params->ie_len && ( NULL != params->ie) )
17352 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017353 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17354 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017355 {
17356 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17357 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17358 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017359 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017360 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017361 tDot11fIEWPA dot11WPAIE;
17362 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017363 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017364
Wilson Yang00256342013-10-10 23:13:38 -070017365 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017366 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17367 params->ie_len, DOT11F_EID_WPA);
17368 if ( NULL != ie )
17369 {
17370 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017371
17372 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17373 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17374 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17375 return -EINVAL;
17376 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017377 // Unpack the WPA IE
17378 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017379 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017380 &ie[2+4],
17381 ie[1] - 4,
17382 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017383 if (DOT11F_FAILED(ret))
17384 {
17385 hddLog(LOGE,
17386 FL("unpack failed status:(0x%08x)"),
17387 ret);
17388 return -EINVAL;
17389 }
17390
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017391 /*Extract the multicast cipher, the encType for unicast
17392 cipher for wpa-none is none*/
17393 encryptionType =
17394 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17395 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017396 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017397
Jeff Johnson295189b2012-06-20 16:38:30 -070017398 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17399
17400 if (0 > status)
17401 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017403 __func__);
17404 return status;
17405 }
17406 }
17407
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017408 pWextState->roamProfile.AuthType.authType[0] =
17409 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017410 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017411 if (params->privacy)
17412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017413 /* Security enabled IBSS, At this time there is no information available
17414 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017415 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017416 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017417 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017418 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017419 *enable privacy bit in beacons */
17420
17421 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17422 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017423 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17424 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017425 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17426 pWextState->roamProfile.EncryptionType.numEntries = 1;
17427 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017428 return status;
17429}
17430
17431/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017432 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017433 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017434 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017435static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017436 struct net_device *dev,
17437 struct cfg80211_ibss_params *params
17438 )
17439{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017440 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017441 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17442 tCsrRoamProfile *pRoamProfile;
17443 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017444 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17445 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017446 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017447
17448 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017449
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17451 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17452 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017453 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017454 "%s: device_mode = %s (%d)", __func__,
17455 hdd_device_modetoString(pAdapter->device_mode),
17456 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017457
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017458 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017459 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017460 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017461 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017462 }
17463
17464 if (NULL == pWextState)
17465 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017466 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017467 __func__);
17468 return -EIO;
17469 }
17470
Agarwal Ashish51325b52014-06-16 16:50:49 +053017471 if (vos_max_concurrent_connections_reached()) {
17472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17473 return -ECONNREFUSED;
17474 }
17475
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017476 /*Try disconnecting if already in connected state*/
17477 status = wlan_hdd_try_disconnect(pAdapter);
17478 if ( 0 > status)
17479 {
17480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17481 " IBSS connection"));
17482 return -EALREADY;
17483 }
17484
Jeff Johnson295189b2012-06-20 16:38:30 -070017485 pRoamProfile = &pWextState->roamProfile;
17486
17487 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17488 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017489 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017490 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017491 return -EINVAL;
17492 }
17493
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017494 /* BSSID is provided by upper layers hence no need to AUTO generate */
17495 if (NULL != params->bssid) {
17496 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17497 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17498 hddLog (VOS_TRACE_LEVEL_ERROR,
17499 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17500 return -EIO;
17501 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017502 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017503 }
krunal sonie9002db2013-11-25 14:24:17 -080017504 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17505 {
17506 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17507 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17508 {
17509 hddLog (VOS_TRACE_LEVEL_ERROR,
17510 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17511 return -EIO;
17512 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017513
17514 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017515 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017516 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017517 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017518
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017520 if (NULL !=
17521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17522 params->chandef.chan)
17523#else
17524 params->channel)
17525#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017526 {
17527 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017528 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17529 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17530 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17531 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017532
17533 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017534 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017535 ieee80211_frequency_to_channel(
17536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17537 params->chandef.chan->center_freq);
17538#else
17539 params->channel->center_freq);
17540#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017541
17542 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17543 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017544 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17546 __func__);
17547 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017548 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017549
17550 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017551 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017552 if (channelNum == validChan[indx])
17553 {
17554 break;
17555 }
17556 }
17557 if (indx >= numChans)
17558 {
17559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017560 __func__, channelNum);
17561 return -EINVAL;
17562 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017563 /* Set the Operational Channel */
17564 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17565 channelNum);
17566 pRoamProfile->ChannelInfo.numOfChannels = 1;
17567 pHddStaCtx->conn_info.operationChannel = channelNum;
17568 pRoamProfile->ChannelInfo.ChannelList =
17569 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017570 }
17571
17572 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017573 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017574 if (status < 0)
17575 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017577 __func__);
17578 return status;
17579 }
17580
17581 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017582 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017583 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017584 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017585
17586 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017589 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017590 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017591}
17592
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017593static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17594 struct net_device *dev,
17595 struct cfg80211_ibss_params *params
17596 )
17597{
17598 int ret = 0;
17599
17600 vos_ssr_protect(__func__);
17601 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17602 vos_ssr_unprotect(__func__);
17603
17604 return ret;
17605}
17606
Jeff Johnson295189b2012-06-20 16:38:30 -070017607/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017608 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017609 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017610 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017611static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 struct net_device *dev
17613 )
17614{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017616 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17617 tCsrRoamProfile *pRoamProfile;
17618 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017619 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017620 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017621#ifdef WLAN_FEATURE_RMC
17622 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17623#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017624
17625 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017626
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017627 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17628 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17629 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017630 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017631 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017632 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017633 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017634 }
17635
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017636 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17637 hdd_device_modetoString(pAdapter->device_mode),
17638 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017639 if (NULL == pWextState)
17640 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017641 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017642 __func__);
17643 return -EIO;
17644 }
17645
17646 pRoamProfile = &pWextState->roamProfile;
17647
17648 /* Issue disconnect only if interface type is set to IBSS */
17649 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17650 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017651 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017652 __func__);
17653 return -EINVAL;
17654 }
17655
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017656#ifdef WLAN_FEATURE_RMC
17657 /* Clearing add IE of beacon */
17658 if (ccmCfgSetStr(pHddCtx->hHal,
17659 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17660 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17661 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17662 {
17663 hddLog (VOS_TRACE_LEVEL_ERROR,
17664 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17665 return -EINVAL;
17666 }
17667 if (ccmCfgSetInt(pHddCtx->hHal,
17668 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17669 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17670 {
17671 hddLog (VOS_TRACE_LEVEL_ERROR,
17672 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17673 __func__);
17674 return -EINVAL;
17675 }
17676
17677 // Reset WNI_CFG_PROBE_RSP Flags
17678 wlan_hdd_reset_prob_rspies(pAdapter);
17679
17680 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17681 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17682 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17683 {
17684 hddLog (VOS_TRACE_LEVEL_ERROR,
17685 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17686 __func__);
17687 return -EINVAL;
17688 }
17689#endif
17690
Jeff Johnson295189b2012-06-20 16:38:30 -070017691 /* Issue Disconnect request */
17692 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017693 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17694 pAdapter->sessionId,
17695 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17696 if (!HAL_STATUS_SUCCESS(hal_status)) {
17697 hddLog(LOGE,
17698 FL("sme_RoamDisconnect failed hal_status(%d)"),
17699 hal_status);
17700 return -EAGAIN;
17701 }
17702 status = wait_for_completion_timeout(
17703 &pAdapter->disconnect_comp_var,
17704 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17705 if (!status) {
17706 hddLog(LOGE,
17707 FL("wait on disconnect_comp_var failed"));
17708 return -ETIMEDOUT;
17709 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017710
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017711 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017712 return 0;
17713}
17714
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017715static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17716 struct net_device *dev
17717 )
17718{
17719 int ret = 0;
17720
17721 vos_ssr_protect(__func__);
17722 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17723 vos_ssr_unprotect(__func__);
17724
17725 return ret;
17726}
17727
Jeff Johnson295189b2012-06-20 16:38:30 -070017728/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017729 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017730 * This function is used to set the phy parameters
17731 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17732 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017733static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017734 u32 changed)
17735{
17736 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17737 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017738 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017739
17740 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017741
17742 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017743 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17744 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017745
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017746 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017747 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017748 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017749 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017750 }
17751
Jeff Johnson295189b2012-06-20 16:38:30 -070017752 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17753 {
17754 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17755 WNI_CFG_RTS_THRESHOLD_STAMAX :
17756 wiphy->rts_threshold;
17757
17758 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017759 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017761 hddLog(VOS_TRACE_LEVEL_ERROR,
17762 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017763 __func__, rts_threshold);
17764 return -EINVAL;
17765 }
17766
17767 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17768 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017769 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017770 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017771 hddLog(VOS_TRACE_LEVEL_ERROR,
17772 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017773 __func__, rts_threshold);
17774 return -EIO;
17775 }
17776
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017777 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017778 rts_threshold);
17779 }
17780
17781 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17782 {
17783 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17784 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17785 wiphy->frag_threshold;
17786
17787 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017788 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017790 hddLog(VOS_TRACE_LEVEL_ERROR,
17791 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017792 frag_threshold);
17793 return -EINVAL;
17794 }
17795
17796 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17797 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017798 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017799 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017800 hddLog(VOS_TRACE_LEVEL_ERROR,
17801 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017802 __func__, frag_threshold);
17803 return -EIO;
17804 }
17805
17806 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17807 frag_threshold);
17808 }
17809
17810 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17811 || (changed & WIPHY_PARAM_RETRY_LONG))
17812 {
17813 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17814 wiphy->retry_short :
17815 wiphy->retry_long;
17816
17817 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17818 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017821 __func__, retry_value);
17822 return -EINVAL;
17823 }
17824
17825 if (changed & WIPHY_PARAM_RETRY_SHORT)
17826 {
17827 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17828 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017829 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017830 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017831 hddLog(VOS_TRACE_LEVEL_ERROR,
17832 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017833 __func__, retry_value);
17834 return -EIO;
17835 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017836 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017837 __func__, retry_value);
17838 }
17839 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17840 {
17841 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17842 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017843 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017844 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017845 hddLog(VOS_TRACE_LEVEL_ERROR,
17846 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017847 __func__, retry_value);
17848 return -EIO;
17849 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017850 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017851 __func__, retry_value);
17852 }
17853 }
17854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017855 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017856 return 0;
17857}
17858
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017859static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17860 u32 changed)
17861{
17862 int ret;
17863
17864 vos_ssr_protect(__func__);
17865 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17866 vos_ssr_unprotect(__func__);
17867
17868 return ret;
17869}
17870
Jeff Johnson295189b2012-06-20 16:38:30 -070017871/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017872 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017873 * This function is used to set the txpower
17874 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017875static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017876#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17877 struct wireless_dev *wdev,
17878#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017879#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017880 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017881#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017882 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017883#endif
17884 int dbm)
17885{
17886 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017887 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017888 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17889 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017890 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017891
17892 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017893
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017894 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17895 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17896 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017897 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017898 if (0 != status)
17899 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017900 return status;
17901 }
17902
17903 hHal = pHddCtx->hHal;
17904
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017905 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17906 dbm, ccmCfgSetCallback,
17907 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017909 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017910 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17911 return -EIO;
17912 }
17913
17914 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17915 dbm);
17916
17917 switch(type)
17918 {
17919 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17920 /* Fall through */
17921 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17922 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17923 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017924 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17925 __func__);
17926 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017927 }
17928 break;
17929 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017931 __func__);
17932 return -EOPNOTSUPP;
17933 break;
17934 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17936 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017937 return -EIO;
17938 }
17939
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017940 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017941 return 0;
17942}
17943
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017944static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17945#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17946 struct wireless_dev *wdev,
17947#endif
17948#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17949 enum tx_power_setting type,
17950#else
17951 enum nl80211_tx_power_setting type,
17952#endif
17953 int dbm)
17954{
17955 int ret;
17956 vos_ssr_protect(__func__);
17957 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17958#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17959 wdev,
17960#endif
17961#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17962 type,
17963#else
17964 type,
17965#endif
17966 dbm);
17967 vos_ssr_unprotect(__func__);
17968
17969 return ret;
17970}
17971
Jeff Johnson295189b2012-06-20 16:38:30 -070017972/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017973 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017974 * This function is used to read the txpower
17975 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017976static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017977#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17978 struct wireless_dev *wdev,
17979#endif
17980 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017981{
17982
17983 hdd_adapter_t *pAdapter;
17984 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017985 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017986
Jeff Johnsone7245742012-09-05 17:12:55 -070017987 ENTER();
17988
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017989 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017990 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017991 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017992 *dbm = 0;
17993 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017994 }
17995
Jeff Johnson295189b2012-06-20 16:38:30 -070017996 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17997 if (NULL == pAdapter)
17998 {
17999 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18000 return -ENOENT;
18001 }
18002
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018003 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18004 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18005 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018006 wlan_hdd_get_classAstats(pAdapter);
18007 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18008
Jeff Johnsone7245742012-09-05 17:12:55 -070018009 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018010 return 0;
18011}
18012
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018013static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18014#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18015 struct wireless_dev *wdev,
18016#endif
18017 int *dbm)
18018{
18019 int ret;
18020
18021 vos_ssr_protect(__func__);
18022 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18023#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18024 wdev,
18025#endif
18026 dbm);
18027 vos_ssr_unprotect(__func__);
18028
18029 return ret;
18030}
18031
Dustin Brown8c1d4092017-07-28 18:08:01 +053018032/*
18033 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18034 * @stats: summary stats to use as a source
18035 * @info: kernel station_info struct to use as a destination
18036 *
18037 * Return: None
18038 */
18039static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18040 struct station_info *info)
18041{
18042 int i;
18043
18044 info->rx_packets = stats->rx_frm_cnt;
18045 info->tx_packets = 0;
18046 info->tx_retries = 0;
18047 info->tx_failed = 0;
18048
18049 for (i = 0; i < 4; ++i) {
18050 info->tx_packets += stats->tx_frm_cnt[i];
18051 info->tx_retries += stats->multiple_retry_cnt[i];
18052 info->tx_failed += stats->fail_cnt[i];
18053 }
18054
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018055#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18056 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018057 info->filled |= STATION_INFO_TX_PACKETS |
18058 STATION_INFO_TX_RETRIES |
18059 STATION_INFO_TX_FAILED |
18060 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018061#else
18062 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18063 BIT(NL80211_STA_INFO_TX_RETRIES) |
18064 BIT(NL80211_STA_INFO_TX_FAILED) |
18065 BIT(NL80211_STA_INFO_RX_PACKETS);
18066#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018067}
18068
18069/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018070 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18071 * @adapter: sap adapter pointer
18072 * @staid: station id of the client
18073 * @rssi: rssi value to fill
18074 *
18075 * Return: None
18076 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018077void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018078wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18079{
18080 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18081
18082 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18083}
18084
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018085#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18086 !defined(WITH_BACKPORTS)
18087static inline void wlan_hdd_fill_station_info_signal(struct station_info
18088 *sinfo)
18089{
18090 sinfo->filled |= STATION_INFO_SIGNAL;
18091}
18092#else
18093static inline void wlan_hdd_fill_station_info_signal(struct station_info
18094 *sinfo)
18095{
18096 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18097}
18098#endif
18099
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018100/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018101 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18102 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018103 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018104 * @info: kernel station_info struct to populate
18105 *
18106 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18107 * support "station dump" and "station get" for SAP vdevs, even though they
18108 * aren't technically stations.
18109 *
18110 * Return: errno
18111 */
18112static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018113wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18115 const u8* mac,
18116#else
18117 u8* mac,
18118#endif
18119 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018120{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018121 v_MACADDR_t *peerMacAddr;
18122 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018123 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018124 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018125
18126 status = wlan_hdd_get_station_stats(adapter);
18127 if (!VOS_IS_STATUS_SUCCESS(status)) {
18128 hddLog(VOS_TRACE_LEVEL_ERROR,
18129 "Failed to get SAP stats; status:%d", status);
18130 return 0;
18131 }
18132
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018133 peerMacAddr = (v_MACADDR_t *)mac;
18134 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18135 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18136 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18137
18138 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18139 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018140 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018141 }
18142
Dustin Brown8c1d4092017-07-28 18:08:01 +053018143 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18144
18145 return 0;
18146}
18147
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018148static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18150 const u8* mac,
18151#else
18152 u8* mac,
18153#endif
18154 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018155{
18156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18157 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18158 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018159 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018160
18161 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18162 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018163
18164 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18165 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18166 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18167 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18168 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18169 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18170 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018171 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018172 tANI_U16 myRate;
18173 tANI_U16 currentRate = 0;
18174 tANI_U8 maxSpeedMCS = 0;
18175 tANI_U8 maxMCSIdx = 0;
18176 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018177 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018178 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018179 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018180
Leo Chang6f8870f2013-03-26 18:11:36 -070018181#ifdef WLAN_FEATURE_11AC
18182 tANI_U32 vht_mcs_map;
18183 eDataRate11ACMaxMcs vhtMaxMcs;
18184#endif /* WLAN_FEATURE_11AC */
18185
Jeff Johnsone7245742012-09-05 17:12:55 -070018186 ENTER();
18187
Dustin Brown8c1d4092017-07-28 18:08:01 +053018188 status = wlan_hdd_validate_context(pHddCtx);
18189 if (0 != status)
18190 {
18191 return status;
18192 }
18193
18194 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018195 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018196
Jeff Johnson295189b2012-06-20 16:38:30 -070018197 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18198 (0 == ssidlen))
18199 {
18200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18201 " Invalid ssidlen, %d", __func__, ssidlen);
18202 /*To keep GUI happy*/
18203 return 0;
18204 }
18205
Mukul Sharma811205f2014-07-09 21:07:30 +053018206 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18207 {
18208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18209 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018210 /* return a cached value */
18211 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018212 return 0;
18213 }
18214
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018215 wlan_hdd_get_station_stats(pAdapter);
18216 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018217
Kiet Lam3b17fc82013-09-27 05:24:08 +053018218 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018219 wlan_hdd_get_snr(pAdapter, &snr);
18220 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018221 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018222 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018223 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018224 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018225
c_hpothu09f19542014-05-30 21:53:31 +053018226 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018227 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18228 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018229 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018230 {
18231 rate_flags = pAdapter->maxRateFlags;
18232 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018233
Jeff Johnson295189b2012-06-20 16:38:30 -070018234 //convert to the UI units of 100kbps
18235 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18236
18237#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018238 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 -070018239 sinfo->signal,
18240 pCfg->reportMaxLinkSpeed,
18241 myRate,
18242 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018243 (int) pCfg->linkSpeedRssiMid,
18244 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018245 (int) rate_flags,
18246 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018247#endif //LINKSPEED_DEBUG_ENABLED
18248
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18250 /* assume basic BW. anything else will override this later */
18251 sinfo->txrate.bw = RATE_INFO_BW_20;
18252#endif
18253
Jeff Johnson295189b2012-06-20 16:38:30 -070018254 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18255 {
18256 // we do not want to necessarily report the current speed
18257 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18258 {
18259 // report the max possible speed
18260 rssidx = 0;
18261 }
18262 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18263 {
18264 // report the max possible speed with RSSI scaling
18265 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18266 {
18267 // report the max possible speed
18268 rssidx = 0;
18269 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018270 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018271 {
18272 // report middle speed
18273 rssidx = 1;
18274 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018275 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18276 {
18277 // report middle speed
18278 rssidx = 2;
18279 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018280 else
18281 {
18282 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018283 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018284 }
18285 }
18286 else
18287 {
18288 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18289 hddLog(VOS_TRACE_LEVEL_ERROR,
18290 "%s: Invalid value for reportMaxLinkSpeed: %u",
18291 __func__, pCfg->reportMaxLinkSpeed);
18292 rssidx = 0;
18293 }
18294
18295 maxRate = 0;
18296
18297 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018298 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18299 OperationalRates, &ORLeng))
18300 {
18301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18302 /*To keep GUI happy*/
18303 return 0;
18304 }
18305
Jeff Johnson295189b2012-06-20 16:38:30 -070018306 for (i = 0; i < ORLeng; i++)
18307 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018308 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018309 {
18310 /* Validate Rate Set */
18311 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18312 {
18313 currentRate = supported_data_rate[j].supported_rate[rssidx];
18314 break;
18315 }
18316 }
18317 /* Update MAX rate */
18318 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18319 }
18320
18321 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018322 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18323 ExtendedRates, &ERLeng))
18324 {
18325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18326 /*To keep GUI happy*/
18327 return 0;
18328 }
18329
Jeff Johnson295189b2012-06-20 16:38:30 -070018330 for (i = 0; i < ERLeng; i++)
18331 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018332 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018333 {
18334 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18335 {
18336 currentRate = supported_data_rate[j].supported_rate[rssidx];
18337 break;
18338 }
18339 }
18340 /* Update MAX rate */
18341 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18342 }
c_hpothu79aab322014-07-14 21:11:01 +053018343
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018344 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018345 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018346 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018347 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018348 {
c_hpothu79aab322014-07-14 21:11:01 +053018349 if (rate_flags & eHAL_TX_RATE_VHT80)
18350 mode = 2;
18351 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18352 mode = 1;
18353 else
18354 mode = 0;
18355
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018356 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18357 MCSRates, &MCSLeng))
18358 {
18359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18360 /*To keep GUI happy*/
18361 return 0;
18362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018363 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018364#ifdef WLAN_FEATURE_11AC
18365 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018366 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018367 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018368 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018369 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018370 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018371 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018372 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018373 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018374 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018375 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018376 maxMCSIdx = 7;
18377 }
18378 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18379 {
18380 maxMCSIdx = 8;
18381 }
18382 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18383 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018384 //VHT20 is supporting 0~8
18385 if (rate_flags & eHAL_TX_RATE_VHT20)
18386 maxMCSIdx = 8;
18387 else
18388 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018389 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018390
c_hpothu79aab322014-07-14 21:11:01 +053018391 if (0 != rssidx)/*check for scaled */
18392 {
18393 //get middle rate MCS index if rssi=1/2
18394 for (i=0; i <= maxMCSIdx; i++)
18395 {
18396 if (sinfo->signal <= rssiMcsTbl[mode][i])
18397 {
18398 maxMCSIdx = i;
18399 break;
18400 }
18401 }
18402 }
18403
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018404 if (rate_flags & eHAL_TX_RATE_VHT80)
18405 {
18406 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18407 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18408 }
18409 else if (rate_flags & eHAL_TX_RATE_VHT40)
18410 {
18411 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18412 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18413 }
18414 else if (rate_flags & eHAL_TX_RATE_VHT20)
18415 {
18416 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18417 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18418 }
18419
Leo Chang6f8870f2013-03-26 18:11:36 -070018420 maxSpeedMCS = 1;
18421 if (currentRate > maxRate)
18422 {
18423 maxRate = currentRate;
18424 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018425
Leo Chang6f8870f2013-03-26 18:11:36 -070018426 }
18427 else
18428#endif /* WLAN_FEATURE_11AC */
18429 {
18430 if (rate_flags & eHAL_TX_RATE_HT40)
18431 {
18432 rateFlag |= 1;
18433 }
18434 if (rate_flags & eHAL_TX_RATE_SGI)
18435 {
18436 rateFlag |= 2;
18437 }
18438
Girish Gowli01abcee2014-07-31 20:18:55 +053018439 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018440 if (rssidx == 1 || rssidx == 2)
18441 {
18442 //get middle rate MCS index if rssi=1/2
18443 for (i=0; i <= 7; i++)
18444 {
18445 if (sinfo->signal <= rssiMcsTbl[mode][i])
18446 {
18447 temp = i+1;
18448 break;
18449 }
18450 }
18451 }
c_hpothu79aab322014-07-14 21:11:01 +053018452
18453 for (i = 0; i < MCSLeng; i++)
18454 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018455 for (j = 0; j < temp; j++)
18456 {
18457 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18458 {
18459 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018460 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018461 break;
18462 }
18463 }
18464 if ((j < temp) && (currentRate > maxRate))
18465 {
18466 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018467 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018468 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018469 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018470 }
18471 }
18472
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018473 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18474 {
18475 maxRate = myRate;
18476 maxSpeedMCS = 1;
18477 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18478 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018479 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018480 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018481 {
18482 maxRate = myRate;
18483 if (rate_flags & eHAL_TX_RATE_LEGACY)
18484 {
18485 maxSpeedMCS = 0;
18486 }
18487 else
18488 {
18489 maxSpeedMCS = 1;
18490 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18491 }
18492 }
18493
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018494 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018495 {
18496 sinfo->txrate.legacy = maxRate;
18497#ifdef LINKSPEED_DEBUG_ENABLED
18498 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18499#endif //LINKSPEED_DEBUG_ENABLED
18500 }
18501 else
18502 {
18503 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018504#ifdef WLAN_FEATURE_11AC
18505 sinfo->txrate.nss = 1;
18506 if (rate_flags & eHAL_TX_RATE_VHT80)
18507 {
18508 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018509#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18510 defined(WITH_BACKPORTS)
18511 sinfo->txrate.bw = RATE_INFO_BW_80;
18512#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018513 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018514#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018515 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018516 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018517 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018518 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18520 defined(WITH_BACKPORTS)
18521 sinfo->txrate.bw = RATE_INFO_BW_40;
18522#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018523 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018524#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018525 }
18526 else if (rate_flags & eHAL_TX_RATE_VHT20)
18527 {
18528 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18529 }
18530#endif /* WLAN_FEATURE_11AC */
18531 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18532 {
18533 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18534 if (rate_flags & eHAL_TX_RATE_HT40)
18535 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018536#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18537 defined(WITH_BACKPORTS)
18538 sinfo->txrate.bw = RATE_INFO_BW_40;
18539#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018540 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018541#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018542 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018543 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018544 if (rate_flags & eHAL_TX_RATE_SGI)
18545 {
18546 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18547 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018548
Jeff Johnson295189b2012-06-20 16:38:30 -070018549#ifdef LINKSPEED_DEBUG_ENABLED
18550 pr_info("Reporting MCS rate %d flags %x\n",
18551 sinfo->txrate.mcs,
18552 sinfo->txrate.flags );
18553#endif //LINKSPEED_DEBUG_ENABLED
18554 }
18555 }
18556 else
18557 {
18558 // report current rate instead of max rate
18559
18560 if (rate_flags & eHAL_TX_RATE_LEGACY)
18561 {
18562 //provide to the UI in units of 100kbps
18563 sinfo->txrate.legacy = myRate;
18564#ifdef LINKSPEED_DEBUG_ENABLED
18565 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18566#endif //LINKSPEED_DEBUG_ENABLED
18567 }
18568 else
18569 {
18570 //must be MCS
18571 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018572#ifdef WLAN_FEATURE_11AC
18573 sinfo->txrate.nss = 1;
18574 if (rate_flags & eHAL_TX_RATE_VHT80)
18575 {
18576 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18577 }
18578 else
18579#endif /* WLAN_FEATURE_11AC */
18580 {
18581 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18582 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018583 if (rate_flags & eHAL_TX_RATE_SGI)
18584 {
18585 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18586 }
18587 if (rate_flags & eHAL_TX_RATE_HT40)
18588 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018589#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18590 defined(WITH_BACKPORTS)
18591 sinfo->txrate.bw = RATE_INFO_BW_40;
18592#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018593 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018594#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018595 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018596#ifdef WLAN_FEATURE_11AC
18597 else if (rate_flags & eHAL_TX_RATE_VHT80)
18598 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018599#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18600 defined(WITH_BACKPORTS)
18601 sinfo->txrate.bw = RATE_INFO_BW_80;
18602#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018603 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018604#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018605 }
18606#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018607#ifdef LINKSPEED_DEBUG_ENABLED
18608 pr_info("Reporting actual MCS rate %d flags %x\n",
18609 sinfo->txrate.mcs,
18610 sinfo->txrate.flags );
18611#endif //LINKSPEED_DEBUG_ENABLED
18612 }
18613 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018614
18615#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18616 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018617 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018618#else
18619 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18620#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018621
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018622 sinfo->tx_packets =
18623 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18624 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18625 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18626 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18627
18628 sinfo->tx_retries =
18629 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18630 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18631 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18632 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18633
18634 sinfo->tx_failed =
18635 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18636 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18637 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18638 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18639
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018640#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18641 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018642 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018643 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018644 STATION_INFO_TX_PACKETS |
18645 STATION_INFO_TX_RETRIES |
18646 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018647#else
18648 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18649 BIT(NL80211_STA_INFO_TX_PACKETS) |
18650 BIT(NL80211_STA_INFO_TX_RETRIES) |
18651 BIT(NL80211_STA_INFO_TX_FAILED);
18652#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018653
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018654 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018655
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018656 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18657 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018658 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18659 &sinfo->txrate, sizeof(sinfo->txrate));
18660
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018661 if (rate_flags & eHAL_TX_RATE_LEGACY)
18662 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18663 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18664 sinfo->rx_packets);
18665 else
18666 hddLog(LOG1,
18667 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18668 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18669 sinfo->tx_packets, sinfo->rx_packets);
18670
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018671 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18672 TRACE_CODE_HDD_CFG80211_GET_STA,
18673 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018674 EXIT();
18675 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018676}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18678static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18679 const u8* mac, struct station_info *sinfo)
18680#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018681static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18682 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018683#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018684{
18685 int ret;
18686
18687 vos_ssr_protect(__func__);
18688 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18689 vos_ssr_unprotect(__func__);
18690
18691 return ret;
18692}
18693
18694static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018695 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018696{
18697 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018698 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018699 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018700 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018701
Jeff Johnsone7245742012-09-05 17:12:55 -070018702 ENTER();
18703
Jeff Johnson295189b2012-06-20 16:38:30 -070018704 if (NULL == pAdapter)
18705 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018707 return -ENODEV;
18708 }
18709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18711 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18712 pAdapter->sessionId, timeout));
18713
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018714 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018715 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018716 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018718 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018719 }
18720
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018721 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18722 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18723 (pHddCtx->cfg_ini->fhostArpOffload) &&
18724 (eConnectionState_Associated ==
18725 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18726 {
Amar Singhald53568e2013-09-26 11:03:45 -070018727
18728 hddLog(VOS_TRACE_LEVEL_INFO,
18729 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018730 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018731 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18732 {
18733 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018734 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018735 __func__, vos_status);
18736 }
18737 }
18738
Jeff Johnson295189b2012-06-20 16:38:30 -070018739 /**The get power cmd from the supplicant gets updated by the nl only
18740 *on successful execution of the function call
18741 *we are oppositely mapped w.r.t mode in the driver
18742 **/
18743 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18744
18745 if (VOS_STATUS_E_FAILURE == vos_status)
18746 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18748 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018749 return -EINVAL;
18750 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018751 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018752 return 0;
18753}
18754
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018755static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18756 struct net_device *dev, bool mode, int timeout)
18757{
18758 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018759
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018760 vos_ssr_protect(__func__);
18761 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18762 vos_ssr_unprotect(__func__);
18763
18764 return ret;
18765}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018766
Jeff Johnson295189b2012-06-20 16:38:30 -070018767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018768static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18769 struct net_device *netdev,
18770 u8 key_index)
18771{
18772 ENTER();
18773 return 0;
18774}
18775
Jeff Johnson295189b2012-06-20 16:38:30 -070018776static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018777 struct net_device *netdev,
18778 u8 key_index)
18779{
18780 int ret;
18781 vos_ssr_protect(__func__);
18782 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18783 vos_ssr_unprotect(__func__);
18784 return ret;
18785}
18786#endif //LINUX_VERSION_CODE
18787
18788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18789static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18790 struct net_device *dev,
18791 struct ieee80211_txq_params *params)
18792{
18793 ENTER();
18794 return 0;
18795}
18796#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18797static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18798 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018799{
Jeff Johnsone7245742012-09-05 17:12:55 -070018800 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018801 return 0;
18802}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018803#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018804
18805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18806static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018807 struct net_device *dev,
18808 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018809{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018810 int ret;
18811
18812 vos_ssr_protect(__func__);
18813 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18814 vos_ssr_unprotect(__func__);
18815 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018816}
18817#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18818static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18819 struct ieee80211_txq_params *params)
18820{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018821 int ret;
18822
18823 vos_ssr_protect(__func__);
18824 ret = __wlan_hdd_set_txq_params(wiphy, params);
18825 vos_ssr_unprotect(__func__);
18826 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018827}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018828#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018829
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018830static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018831 struct net_device *dev,
18832 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018833{
18834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018835 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018836 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018837 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018838 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018839 v_CONTEXT_t pVosContext = NULL;
18840 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018841
Jeff Johnsone7245742012-09-05 17:12:55 -070018842 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018843
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018844 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018845 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018846 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018847 return -EINVAL;
18848 }
18849
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018850 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18851 TRACE_CODE_HDD_CFG80211_DEL_STA,
18852 pAdapter->sessionId, pAdapter->device_mode));
18853
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18855 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018856 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018857 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018858 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018859 }
18860
Jeff Johnson295189b2012-06-20 16:38:30 -070018861 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018862 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018863 )
18864 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018865 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18866 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18867 if(pSapCtx == NULL){
18868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18869 FL("psapCtx is NULL"));
18870 return -ENOENT;
18871 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018872 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18873 {
18874 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18875 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18876 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18877 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018878 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018879 {
18880 v_U16_t i;
18881 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18882 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018883 if ((pSapCtx->aStaInfo[i].isUsed) &&
18884 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018885 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018886 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018887 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018888 ETHER_ADDR_LEN);
18889
Jeff Johnson295189b2012-06-20 16:38:30 -070018890 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018891 "%s: Delete STA with MAC::"
18892 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018893 __func__,
18894 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18895 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018896 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018897 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018898 }
18899 }
18900 }
18901 else
18902 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018903
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018904 vos_status = hdd_softap_GetStaId(pAdapter,
18905 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018906 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18907 {
18908 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018909 "%s: Skip this DEL STA as this is not used::"
18910 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018911 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018912 return -ENOENT;
18913 }
18914
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018915 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018916 {
18917 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018918 "%s: Skip this DEL STA as deauth is in progress::"
18919 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018920 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018921 return -ENOENT;
18922 }
18923
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018924 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018925
Jeff Johnson295189b2012-06-20 16:38:30 -070018926 hddLog(VOS_TRACE_LEVEL_INFO,
18927 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018928 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018929 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018930 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018931
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018932 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018933 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18934 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018935 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018936 hddLog(VOS_TRACE_LEVEL_INFO,
18937 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018938 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018939 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018940 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018941 return -ENOENT;
18942 }
18943
Jeff Johnson295189b2012-06-20 16:38:30 -070018944 }
18945 }
18946
18947 EXIT();
18948
18949 return 0;
18950}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018951
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018952#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018953int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018954 struct net_device *dev,
18955 struct station_del_parameters *param)
18956#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018958int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018959 struct net_device *dev, const u8 *mac)
18960#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018961int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018962 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018963#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018964#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018965{
18966 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018967 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018968
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018969 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018970
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018971#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018972 if (NULL == param) {
18973 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018974 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018975 return -EINVAL;
18976 }
18977
18978 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18979 param->subtype, &delStaParams);
18980
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018981#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018982 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018983 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018984#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018985 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18986
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018987 vos_ssr_unprotect(__func__);
18988
18989 return ret;
18990}
18991
18992static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018993 struct net_device *dev,
18994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18995 const u8 *mac,
18996#else
18997 u8 *mac,
18998#endif
18999 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019000{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019001 hdd_adapter_t *pAdapter;
19002 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019003 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019004#ifdef FEATURE_WLAN_TDLS
19005 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019006
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019007 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019008
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019009 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19010 if (NULL == pAdapter)
19011 {
19012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19013 "%s: Adapter is NULL",__func__);
19014 return -EINVAL;
19015 }
19016 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19017 status = wlan_hdd_validate_context(pHddCtx);
19018 if (0 != status)
19019 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019020 return status;
19021 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019022
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019023 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19024 TRACE_CODE_HDD_CFG80211_ADD_STA,
19025 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019026 mask = params->sta_flags_mask;
19027
19028 set = params->sta_flags_set;
19029
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019031 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19032 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019033
19034 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19035 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019036 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019037 }
19038 }
19039#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019040 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019041 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019042}
19043
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19045static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19046 struct net_device *dev, const u8 *mac,
19047 struct station_parameters *params)
19048#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019049static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19050 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019051#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019052{
19053 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019054
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019055 vos_ssr_protect(__func__);
19056 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19057 vos_ssr_unprotect(__func__);
19058
19059 return ret;
19060}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019061#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019062
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019063static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019064 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019065{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19067 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019068 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019069 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019070 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019071 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019072
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019073 ENTER();
19074
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019075 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019076 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019077 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019079 return -EINVAL;
19080 }
19081
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019082 if (!pmksa) {
19083 hddLog(LOGE, FL("pmksa is NULL"));
19084 return -EINVAL;
19085 }
19086
19087 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019088 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019089 pmksa->bssid, pmksa->pmkid);
19090 return -EINVAL;
19091 }
19092
19093 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19094 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019096 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19097 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019098 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019100 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019101 }
19102
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019103 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019104 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19105
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019106 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19107 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019108
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019109 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019110 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019111 &pmk_id, 1, FALSE);
19112
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019113 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19114 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19115 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019116
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019117 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019118 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019119}
19120
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019121static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19122 struct cfg80211_pmksa *pmksa)
19123{
19124 int ret;
19125
19126 vos_ssr_protect(__func__);
19127 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19128 vos_ssr_unprotect(__func__);
19129
19130 return ret;
19131}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019132
Wilson Yang6507c4e2013-10-01 20:11:19 -070019133
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019134static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019135 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019136{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19138 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019139 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019140 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019141
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019142 ENTER();
19143
Wilson Yang6507c4e2013-10-01 20:11:19 -070019144 /* Validate pAdapter */
19145 if (NULL == pAdapter)
19146 {
19147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19148 return -EINVAL;
19149 }
19150
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019151 if (!pmksa) {
19152 hddLog(LOGE, FL("pmksa is NULL"));
19153 return -EINVAL;
19154 }
19155
19156 if (!pmksa->bssid) {
19157 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19158 return -EINVAL;
19159 }
19160
Kiet Lam98c46a12014-10-31 15:34:57 -070019161 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19162 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19163
Wilson Yang6507c4e2013-10-01 20:11:19 -070019164 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19165 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019166 if (0 != status)
19167 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019168 return status;
19169 }
19170
19171 /*Retrieve halHandle*/
19172 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19173
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019174 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19175 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19176 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019177 /* Delete the PMKID CSR cache */
19178 if (eHAL_STATUS_SUCCESS !=
19179 sme_RoamDelPMKIDfromCache(halHandle,
19180 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19181 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19182 MAC_ADDR_ARRAY(pmksa->bssid));
19183 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019184 }
19185
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019186 EXIT();
19187 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019188}
19189
Wilson Yang6507c4e2013-10-01 20:11:19 -070019190
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019191static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19192 struct cfg80211_pmksa *pmksa)
19193{
19194 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019195
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019196 vos_ssr_protect(__func__);
19197 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19198 vos_ssr_unprotect(__func__);
19199
19200 return ret;
19201
19202}
19203
19204static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019205{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19207 tHalHandle halHandle;
19208 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019209 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019210
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019211 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019212
19213 /* Validate pAdapter */
19214 if (NULL == pAdapter)
19215 {
19216 hddLog(VOS_TRACE_LEVEL_ERROR,
19217 "%s: Invalid Adapter" ,__func__);
19218 return -EINVAL;
19219 }
19220
19221 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19222 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019223 if (0 != status)
19224 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019225 return status;
19226 }
19227
19228 /*Retrieve halHandle*/
19229 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19230
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019231 /* Flush the PMKID cache in CSR */
19232 if (eHAL_STATUS_SUCCESS !=
19233 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19234 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19235 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019236 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019237 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019238 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019239}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019240
19241static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19242{
19243 int ret;
19244
19245 vos_ssr_protect(__func__);
19246 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19247 vos_ssr_unprotect(__func__);
19248
19249 return ret;
19250}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019251#endif
19252
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019253#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019254static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19255 struct net_device *dev,
19256 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019257{
19258 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19259 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019260 hdd_context_t *pHddCtx;
19261 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019262
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019263 ENTER();
19264
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019265 if (NULL == pAdapter)
19266 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019268 return -ENODEV;
19269 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019270 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19271 ret = wlan_hdd_validate_context(pHddCtx);
19272 if (0 != ret)
19273 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019274 return ret;
19275 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019276 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019277 if (NULL == pHddStaCtx)
19278 {
19279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19280 return -EINVAL;
19281 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019282
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019283 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19284 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19285 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019286 // Added for debug on reception of Re-assoc Req.
19287 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19288 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019289 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019290 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019291 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019292 }
19293
19294#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019295 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019296 ftie->ie_len);
19297#endif
19298
19299 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019300 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19301 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019302 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019303
19304 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019305 return 0;
19306}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019307
19308static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19309 struct net_device *dev,
19310 struct cfg80211_update_ft_ies_params *ftie)
19311{
19312 int ret;
19313
19314 vos_ssr_protect(__func__);
19315 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19316 vos_ssr_unprotect(__func__);
19317
19318 return ret;
19319}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019320#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019321
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019322#ifdef FEATURE_WLAN_SCAN_PNO
19323
19324void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19325 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19326{
19327 int ret;
19328 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19329 hdd_context_t *pHddCtx;
19330
Nirav Shah80830bf2013-12-31 16:35:12 +053019331 ENTER();
19332
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019333 if (NULL == pAdapter)
19334 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019336 "%s: HDD adapter is Null", __func__);
19337 return ;
19338 }
19339
19340 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19341 if (NULL == pHddCtx)
19342 {
19343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19344 "%s: HDD context is Null!!!", __func__);
19345 return ;
19346 }
19347
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019348 spin_lock(&pHddCtx->schedScan_lock);
19349 if (TRUE == pHddCtx->isWiphySuspended)
19350 {
19351 pHddCtx->isSchedScanUpdatePending = TRUE;
19352 spin_unlock(&pHddCtx->schedScan_lock);
19353 hddLog(VOS_TRACE_LEVEL_INFO,
19354 "%s: Update cfg80211 scan database after it resume", __func__);
19355 return ;
19356 }
19357 spin_unlock(&pHddCtx->schedScan_lock);
19358
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019359 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19360
19361 if (0 > ret)
19362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019363 else
19364 {
19365 /* Acquire wakelock to handle the case where APP's tries to suspend
19366 * immediatly after the driver gets connect request(i.e after pno)
19367 * from supplicant, this result in app's is suspending and not able
19368 * to process the connect request to AP */
19369 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19370 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019371 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19373 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019374}
19375
19376/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019377 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019378 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019379 */
19380static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19381{
19382 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19383 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019384 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019385 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19386 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019387
19388 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19389 {
19390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19391 "%s: PNO is allowed only in STA interface", __func__);
19392 return eHAL_STATUS_FAILURE;
19393 }
19394
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019395 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19396
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019397 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019398 * active sessions. PNO is allowed only in case when sap session
19399 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019400 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019401 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19402 {
19403 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019404 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019405
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019406 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19407 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19408 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19409 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019410 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19411 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019412 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019413 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019414 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019415 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019416 }
19417 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19418 pAdapterNode = pNext;
19419 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019420 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019421}
19422
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019423void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19424{
19425 hdd_adapter_t *pAdapter = callbackContext;
19426 hdd_context_t *pHddCtx;
19427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019428 ENTER();
19429
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019430 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19431 {
19432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19433 FL("Invalid adapter or adapter has invalid magic"));
19434 return;
19435 }
19436
19437 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19438 if (0 != wlan_hdd_validate_context(pHddCtx))
19439 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019440 return;
19441 }
19442
c_hpothub53c45d2014-08-18 16:53:14 +053019443 if (VOS_STATUS_SUCCESS != status)
19444 {
19445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019446 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019447 pHddCtx->isPnoEnable = FALSE;
19448 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019449
19450 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19451 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019452 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019453}
19454
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019455#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19456 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19457/**
19458 * hdd_config_sched_scan_plan() - configures the sched scan plans
19459 * from the framework.
19460 * @pno_req: pointer to PNO scan request
19461 * @request: pointer to scan request from framework
19462 *
19463 * Return: None
19464 */
19465static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19466 struct cfg80211_sched_scan_request *request,
19467 hdd_context_t *hdd_ctx)
19468{
19469 v_U32_t i = 0;
19470
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019471 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019472 for (i = 0; i < request->n_scan_plans; i++)
19473 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019474 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19475 request->scan_plans[i].iterations;
19476 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19477 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019478 }
19479}
19480#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019481static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019482 struct cfg80211_sched_scan_request *request,
19483 hdd_context_t *hdd_ctx)
19484{
19485 v_U32_t i, temp_int;
19486 /* Driver gets only one time interval which is hardcoded in
19487 * supplicant for 10000ms. Taking power consumption into account 6
19488 * timers will be used, Timervalue is increased exponentially
19489 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19490 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19491 * If it is set to 0 only one timer will be used and PNO scan cycle
19492 * will be repeated after each interval specified by supplicant
19493 * till PNO is disabled.
19494 */
19495 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019496 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019497 HDD_PNO_SCAN_TIMERS_SET_ONE;
19498 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019499 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019500 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19501
19502 temp_int = (request->interval)/1000;
19503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19504 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19505 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019506 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019507 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019508 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019509 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019510 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019511 temp_int *= 2;
19512 }
19513 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019514 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019515}
19516#endif
19517
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019518/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019519 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19520 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019521 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019522static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019523 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19524{
19525 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019526 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019527 hdd_context_t *pHddCtx;
19528 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019529 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019530 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19531 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019532 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19533 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019534 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019535 hdd_config_t *pConfig = NULL;
19536 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019537
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019538 ENTER();
19539
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019540 if (NULL == pAdapter)
19541 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019543 "%s: HDD adapter is Null", __func__);
19544 return -ENODEV;
19545 }
19546
19547 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019548 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019549
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019550 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019551 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019552 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019553 }
19554
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019555 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019556 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19557 if (NULL == hHal)
19558 {
19559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19560 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019561 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019562 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19564 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19565 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019566 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019567 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019568 {
19569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19570 "%s: aborting the existing scan is unsuccessfull", __func__);
19571 return -EBUSY;
19572 }
19573
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019574 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019575 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019577 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019578 return -EBUSY;
19579 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019580
c_hpothu37f21312014-04-09 21:49:54 +053019581 if (TRUE == pHddCtx->isPnoEnable)
19582 {
19583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19584 FL("already PNO is enabled"));
19585 return -EBUSY;
19586 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019587
19588 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19589 {
19590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19591 "%s: abort ROC failed ", __func__);
19592 return -EBUSY;
19593 }
19594
c_hpothu37f21312014-04-09 21:49:54 +053019595 pHddCtx->isPnoEnable = TRUE;
19596
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019597 pnoRequest.enable = 1; /*Enable PNO */
19598 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019599
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019600 if (( !pnoRequest.ucNetworksCount ) ||
19601 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019602 {
19603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019604 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019605 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019606 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019607 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019608 goto error;
19609 }
19610
19611 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19612 {
19613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019614 "%s: Incorrect number of channels %d",
19615 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019616 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019617 goto error;
19618 }
19619
19620 /* Framework provides one set of channels(all)
19621 * common for all saved profile */
19622 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19623 channels_allowed, &num_channels_allowed))
19624 {
19625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19626 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019627 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019628 goto error;
19629 }
19630 /* Checking each channel against allowed channel list */
19631 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019632 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019633 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019634 char chList [(request->n_channels*5)+1];
19635 int len;
19636 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019637 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019638 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019639 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019640 if (request->channels[i]->hw_value == channels_allowed[indx])
19641 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019642 if ((!pConfig->enableDFSPnoChnlScan) &&
19643 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19644 {
19645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19646 "%s : Dropping DFS channel : %d",
19647 __func__,channels_allowed[indx]);
19648 num_ignore_dfs_ch++;
19649 break;
19650 }
19651
Nirav Shah80830bf2013-12-31 16:35:12 +053019652 valid_ch[num_ch++] = request->channels[i]->hw_value;
19653 len += snprintf(chList+len, 5, "%d ",
19654 request->channels[i]->hw_value);
19655 break ;
19656 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019657 }
19658 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019659 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019660
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019661 /*If all channels are DFS and dropped, then ignore the PNO request*/
19662 if (num_ignore_dfs_ch == request->n_channels)
19663 {
19664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19665 "%s : All requested channels are DFS channels", __func__);
19666 ret = -EINVAL;
19667 goto error;
19668 }
19669 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019670
19671 pnoRequest.aNetworks =
19672 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19673 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019674 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019675 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19676 FL("failed to allocate memory aNetworks %u"),
19677 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19678 goto error;
19679 }
19680 vos_mem_zero(pnoRequest.aNetworks,
19681 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19682
19683 /* Filling per profile params */
19684 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19685 {
19686 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019687 request->match_sets[i].ssid.ssid_len;
19688
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019689 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19690 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019691 {
19692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019693 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019694 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019695 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019696 goto error;
19697 }
19698
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019699 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019700 request->match_sets[i].ssid.ssid,
19701 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19703 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019704 i, pnoRequest.aNetworks[i].ssId.ssId);
19705 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19706 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19707 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019708
19709 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019710 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19711 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019712
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019713 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019714 }
19715
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019716 for (i = 0; i < request->n_ssids; i++)
19717 {
19718 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019719 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019720 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019721 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019722 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019723 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019724 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019725 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019726 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019727 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019728 break;
19729 }
19730 j++;
19731 }
19732 }
19733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19734 "Number of hidden networks being Configured = %d",
19735 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019737 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019738
19739 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19740 if (pnoRequest.p24GProbeTemplate == NULL)
19741 {
19742 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19743 FL("failed to allocate memory p24GProbeTemplate %u"),
19744 SIR_PNO_MAX_PB_REQ_SIZE);
19745 goto error;
19746 }
19747
19748 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19749 if (pnoRequest.p5GProbeTemplate == NULL)
19750 {
19751 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19752 FL("failed to allocate memory p5GProbeTemplate %u"),
19753 SIR_PNO_MAX_PB_REQ_SIZE);
19754 goto error;
19755 }
19756
19757 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19758 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19759
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019760 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19761 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019762 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019763 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19764 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19765 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019766
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019767 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19768 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19769 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019770 }
19771
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019772 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019773
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019774 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019775
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019776 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019777 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19778 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019779 pAdapter->pno_req_status = 0;
19780
Nirav Shah80830bf2013-12-31 16:35:12 +053019781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19782 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019783 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19784 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019785
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019786 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019787 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019788 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19789 if (eHAL_STATUS_SUCCESS != status)
19790 {
19791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019792 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019793 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019794 goto error;
19795 }
19796
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019797 ret = wait_for_completion_timeout(
19798 &pAdapter->pno_comp_var,
19799 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19800 if (0 >= ret)
19801 {
19802 // Did not receive the response for PNO enable in time.
19803 // Assuming the PNO enable was success.
19804 // Returning error from here, because we timeout, results
19805 // in side effect of Wifi (Wifi Setting) not to work.
19806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19807 FL("Timed out waiting for PNO to be Enabled"));
19808 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019809 }
19810
19811 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019812 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019813
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019814error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19816 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019817 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019818 if (pnoRequest.aNetworks)
19819 vos_mem_free(pnoRequest.aNetworks);
19820 if (pnoRequest.p24GProbeTemplate)
19821 vos_mem_free(pnoRequest.p24GProbeTemplate);
19822 if (pnoRequest.p5GProbeTemplate)
19823 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019824
19825 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019826 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019827}
19828
19829/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019830 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19831 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019832 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019833static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19834 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19835{
19836 int ret;
19837
19838 vos_ssr_protect(__func__);
19839 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19840 vos_ssr_unprotect(__func__);
19841
19842 return ret;
19843}
19844
19845/*
19846 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19847 * Function to disable PNO
19848 */
19849static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019850 struct net_device *dev)
19851{
19852 eHalStatus status = eHAL_STATUS_FAILURE;
19853 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19854 hdd_context_t *pHddCtx;
19855 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019856 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019857 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019858
19859 ENTER();
19860
19861 if (NULL == pAdapter)
19862 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019864 "%s: HDD adapter is Null", __func__);
19865 return -ENODEV;
19866 }
19867
19868 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019869
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019870 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019871 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019873 "%s: HDD context is Null", __func__);
19874 return -ENODEV;
19875 }
19876
19877 /* The return 0 is intentional when isLogpInProgress and
19878 * isLoadUnloadInProgress. We did observe a crash due to a return of
19879 * failure in sched_scan_stop , especially for a case where the unload
19880 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19881 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19882 * success. If it returns a failure , then its next invocation due to the
19883 * clean up of the second interface will have the dev pointer corresponding
19884 * to the first one leading to a crash.
19885 */
19886 if (pHddCtx->isLogpInProgress)
19887 {
19888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19889 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019890 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019891 return ret;
19892 }
19893
Mihir Shete18156292014-03-11 15:38:30 +053019894 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019895 {
19896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19897 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19898 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019899 }
19900
19901 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19902 if (NULL == hHal)
19903 {
19904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19905 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019906 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019907 }
19908
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019909 pnoRequest.enable = 0; /* Disable PNO */
19910 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019911
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019912 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19913 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19914 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019915
19916 INIT_COMPLETION(pAdapter->pno_comp_var);
19917 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19918 pnoRequest.callbackContext = pAdapter;
19919 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019920 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019921 pAdapter->sessionId,
19922 NULL, pAdapter);
19923 if (eHAL_STATUS_SUCCESS != status)
19924 {
19925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19926 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019927 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019928 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019929 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019930 ret = wait_for_completion_timeout(
19931 &pAdapter->pno_comp_var,
19932 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19933 if (0 >= ret)
19934 {
19935 // Did not receive the response for PNO disable in time.
19936 // Assuming the PNO disable was success.
19937 // Returning error from here, because we timeout, results
19938 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019940 FL("Timed out waiting for PNO to be disabled"));
19941 ret = 0;
19942 }
19943
19944 ret = pAdapter->pno_req_status;
19945 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019946
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019947error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019949 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019950
19951 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019952 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019953}
19954
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019955/*
19956 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19957 * NL interface to disable PNO
19958 */
19959static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19960 struct net_device *dev)
19961{
19962 int ret;
19963
19964 vos_ssr_protect(__func__);
19965 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19966 vos_ssr_unprotect(__func__);
19967
19968 return ret;
19969}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019970#endif /*FEATURE_WLAN_SCAN_PNO*/
19971
19972
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019973#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019974#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019975static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19976 struct net_device *dev,
19977 u8 *peer, u8 action_code,
19978 u8 dialog_token,
19979 u16 status_code, u32 peer_capability,
19980 const u8 *buf, size_t len)
19981#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019982#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19983 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019984static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19985 struct net_device *dev,
19986 const u8 *peer, u8 action_code,
19987 u8 dialog_token, u16 status_code,
19988 u32 peer_capability, bool initiator,
19989 const u8 *buf, size_t len)
19990#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19991static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19992 struct net_device *dev,
19993 const u8 *peer, u8 action_code,
19994 u8 dialog_token, u16 status_code,
19995 u32 peer_capability, const u8 *buf,
19996 size_t len)
19997#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19998static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19999 struct net_device *dev,
20000 u8 *peer, u8 action_code,
20001 u8 dialog_token,
20002 u16 status_code, u32 peer_capability,
20003 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020004#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020005static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20006 struct net_device *dev,
20007 u8 *peer, u8 action_code,
20008 u8 dialog_token,
20009 u16 status_code, const u8 *buf,
20010 size_t len)
20011#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020012#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020013{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020014 hdd_adapter_t *pAdapter;
20015 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020016 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020017 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020018 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020019 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020020 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020021 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020022#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020023 u32 peer_capability = 0;
20024#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020025 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020026 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020027 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020028
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020029 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20030 if (NULL == pAdapter)
20031 {
20032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20033 "%s: Adapter is NULL",__func__);
20034 return -EINVAL;
20035 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20037 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20038 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020039
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020040 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020041 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020044 "Invalid arguments");
20045 return -EINVAL;
20046 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020047
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020048 if (pHddCtx->isLogpInProgress)
20049 {
20050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20051 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020052 wlan_hdd_tdls_set_link_status(pAdapter,
20053 peer,
20054 eTDLS_LINK_IDLE,
20055 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020056 return -EBUSY;
20057 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020058
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020059 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20060 {
20061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20062 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20063 return -EAGAIN;
20064 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020065
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020066 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20067 if (!pHddTdlsCtx) {
20068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20069 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020070 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020071 }
20072
Hoonki Lee27511902013-03-14 18:19:06 -070020073 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020074 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020076 "%s: TDLS mode is disabled OR not enabled in FW."
20077 MAC_ADDRESS_STR " action %d declined.",
20078 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020079 return -ENOTSUPP;
20080 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020081
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020082 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20083
20084 if( NULL == pHddStaCtx )
20085 {
20086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20087 "%s: HDD station context NULL ",__func__);
20088 return -EINVAL;
20089 }
20090
20091 /* STA should be connected and authenticated
20092 * before sending any TDLS frames
20093 */
20094 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20095 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20096 {
20097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20098 "STA is not connected or unauthenticated. "
20099 "connState %u, uIsAuthenticated %u",
20100 pHddStaCtx->conn_info.connState,
20101 pHddStaCtx->conn_info.uIsAuthenticated);
20102 return -EAGAIN;
20103 }
20104
Hoonki Lee27511902013-03-14 18:19:06 -070020105 /* other than teardown frame, other mgmt frames are not sent if disabled */
20106 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20107 {
20108 /* if tdls_mode is disabled to respond to peer's request */
20109 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20110 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020112 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020113 " TDLS mode is disabled. action %d declined.",
20114 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020115
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020116 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020117 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020118
20119 if (vos_max_concurrent_connections_reached())
20120 {
20121 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20122 return -EINVAL;
20123 }
Hoonki Lee27511902013-03-14 18:19:06 -070020124 }
20125
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020126 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20127 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020128 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020129 {
20130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020131 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020132 " TDLS setup is ongoing. action %d declined.",
20133 __func__, MAC_ADDR_ARRAY(peer), action_code);
20134 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020135 }
20136 }
20137
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020138 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20139 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020140 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020141 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20142 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020143 {
20144 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20145 we return error code at 'add_station()'. Hence we have this
20146 check again in addtion to add_station().
20147 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020148 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020149 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20151 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020152 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20153 __func__, MAC_ADDR_ARRAY(peer), action_code,
20154 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020155 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020156 }
20157 else
20158 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020159 /* maximum reached. tweak to send error code to peer and return
20160 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020161 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20163 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020164 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20165 __func__, MAC_ADDR_ARRAY(peer), status_code,
20166 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020167 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020168 /* fall through to send setup resp with failure status
20169 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020170 }
20171 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020172 else
20173 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020174 mutex_lock(&pHddCtx->tdls_lock);
20175 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020176 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020177 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020178 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020180 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20181 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020182 return -EPERM;
20183 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020184 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020185 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020186 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020187
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020189 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020190 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20191 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020192
Hoonki Leea34dd892013-02-05 22:56:02 -080020193 /*Except teardown responder will not be used so just make 0*/
20194 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020195 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020196 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020197
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020198 mutex_lock(&pHddCtx->tdls_lock);
20199 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020200
20201 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20202 responder = pTdlsPeer->is_responder;
20203 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020204 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020206 "%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 -070020207 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20208 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020209 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020210 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020211 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020212 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020213 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020214
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020215 /* Discard TDLS setup if peer is removed by user app */
20216 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20217 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20218 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20219 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20220
20221 mutex_lock(&pHddCtx->tdls_lock);
20222 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20223 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20224 mutex_unlock(&pHddCtx->tdls_lock);
20225 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20226 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20227 MAC_ADDR_ARRAY(peer), action_code);
20228 return -EINVAL;
20229 }
20230 mutex_unlock(&pHddCtx->tdls_lock);
20231 }
20232
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020233 /* For explicit trigger of DIS_REQ come out of BMPS for
20234 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020235 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020236 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020237 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20238 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020239 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020240 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020242 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20243 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020244 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20245 if (status != VOS_STATUS_SUCCESS) {
20246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020247 } else {
20248 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020249 }
Hoonki Lee14621352013-04-16 17:51:19 -070020250 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020251 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020252 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20254 }
20255 }
Hoonki Lee14621352013-04-16 17:51:19 -070020256 }
20257
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020258 /* make sure doesn't call send_mgmt() while it is pending */
20259 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20260 {
20261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020262 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020263 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020264 ret = -EBUSY;
20265 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020266 }
20267
20268 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020269 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20270
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020271 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20272 pAdapter->sessionId, peer, action_code, dialog_token,
20273 status_code, peer_capability, (tANI_U8 *)buf, len,
20274 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020275
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020276 if (VOS_STATUS_SUCCESS != status)
20277 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20279 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020280 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020281 ret = -EINVAL;
20282 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020283 }
20284
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20286 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20287 WAIT_TIME_TDLS_MGMT);
20288
Hoonki Leed37cbb32013-04-20 00:31:14 -070020289 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20290 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20291
20292 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020293 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020295 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020296 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020297 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020298
20299 if (pHddCtx->isLogpInProgress)
20300 {
20301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20302 "%s: LOGP in Progress. Ignore!!!", __func__);
20303 return -EAGAIN;
20304 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020305 if (rc <= 0)
20306 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20307 WLAN_LOG_INDICATOR_HOST_DRIVER,
20308 WLAN_LOG_REASON_HDD_TIME_OUT,
20309 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020310
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020311 ret = -EINVAL;
20312 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020313 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020314 else
20315 {
20316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20317 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20318 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20319 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020320
Gopichand Nakkala05922802013-03-14 12:23:19 -070020321 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020322 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020323 ret = max_sta_failed;
20324 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020325 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020326
Hoonki Leea34dd892013-02-05 22:56:02 -080020327 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20328 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020329 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20331 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020332 }
20333 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20334 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020335 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20337 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020338 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020339
20340 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020341
20342tx_failed:
20343 /* add_station will be called before sending TDLS_SETUP_REQ and
20344 * TDLS_SETUP_RSP and as part of add_station driver will enable
20345 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20346 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20347 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20348 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20349 */
20350
20351 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20352 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20353 wlan_hdd_tdls_check_bmps(pAdapter);
20354 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020355}
20356
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020357#if TDLS_MGMT_VERSION2
20358static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20359 u8 *peer, u8 action_code, u8 dialog_token,
20360 u16 status_code, u32 peer_capability,
20361 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020362#else /* TDLS_MGMT_VERSION2 */
20363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20364static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20365 struct net_device *dev,
20366 const u8 *peer, u8 action_code,
20367 u8 dialog_token, u16 status_code,
20368 u32 peer_capability, bool initiator,
20369 const u8 *buf, size_t len)
20370#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20371static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20372 struct net_device *dev,
20373 const u8 *peer, u8 action_code,
20374 u8 dialog_token, u16 status_code,
20375 u32 peer_capability, const u8 *buf,
20376 size_t len)
20377#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20378static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20379 struct net_device *dev,
20380 u8 *peer, u8 action_code,
20381 u8 dialog_token,
20382 u16 status_code, u32 peer_capability,
20383 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020384#else
20385static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20386 u8 *peer, u8 action_code, u8 dialog_token,
20387 u16 status_code, const u8 *buf, size_t len)
20388#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020389#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020390{
20391 int ret;
20392
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020393 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020394#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020395 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20396 dialog_token, status_code,
20397 peer_capability, buf, len);
20398#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20400 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020401 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20402 dialog_token, status_code,
20403 peer_capability, initiator,
20404 buf, len);
20405#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20406 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20407 dialog_token, status_code,
20408 peer_capability, buf, len);
20409#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20410 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20411 dialog_token, status_code,
20412 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020413#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020414 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20415 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020416#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020417#endif
20418 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020419
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020420 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020421}
Atul Mittal115287b2014-07-08 13:26:33 +053020422
20423int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020424#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20425 const u8 *peer,
20426#else
Atul Mittal115287b2014-07-08 13:26:33 +053020427 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020428#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020429 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020430 cfg80211_exttdls_callback callback)
20431{
20432
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020433 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020434 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020435 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20437 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20438 __func__, MAC_ADDR_ARRAY(peer));
20439
20440 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20441 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20442
20443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020444 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20445 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20446 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020447 return -ENOTSUPP;
20448 }
20449
20450 /* To cater the requirement of establishing the TDLS link
20451 * irrespective of the data traffic , get an entry of TDLS peer.
20452 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020453 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020454 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20455 if (pTdlsPeer == NULL) {
20456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20457 "%s: peer " MAC_ADDRESS_STR " not existing",
20458 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020459 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020460 return -EINVAL;
20461 }
20462
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020463 /* check FW TDLS Off Channel capability */
20464 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020465 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020466 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020467 {
20468 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20469 pTdlsPeer->peerParams.global_operating_class =
20470 tdls_peer_params->global_operating_class;
20471 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20472 pTdlsPeer->peerParams.min_bandwidth_kbps =
20473 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020474 /* check configured channel is valid, non dfs and
20475 * not current operating channel */
20476 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20477 tdls_peer_params->channel)) &&
20478 (pHddStaCtx) &&
20479 (tdls_peer_params->channel !=
20480 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020481 {
20482 pTdlsPeer->isOffChannelConfigured = TRUE;
20483 }
20484 else
20485 {
20486 pTdlsPeer->isOffChannelConfigured = FALSE;
20487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20488 "%s: Configured Tdls Off Channel is not valid", __func__);
20489
20490 }
20491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020492 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20493 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020494 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020495 pTdlsPeer->isOffChannelConfigured,
20496 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020497 }
20498 else
20499 {
20500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020501 "%s: TDLS off channel FW capability %d, "
20502 "host capab %d or Invalid TDLS Peer Params", __func__,
20503 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20504 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020505 }
20506
Atul Mittal115287b2014-07-08 13:26:33 +053020507 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20508
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020509 mutex_unlock(&pHddCtx->tdls_lock);
20510
Atul Mittal115287b2014-07-08 13:26:33 +053020511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20512 " %s TDLS Add Force Peer Failed",
20513 __func__);
20514 return -EINVAL;
20515 }
20516 /*EXT TDLS*/
20517
20518 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020519 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20521 " %s TDLS set callback Failed",
20522 __func__);
20523 return -EINVAL;
20524 }
20525
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020526 mutex_unlock(&pHddCtx->tdls_lock);
20527
Atul Mittal115287b2014-07-08 13:26:33 +053020528 return(0);
20529
20530}
20531
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020532int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20534 const u8 *peer
20535#else
20536 u8 *peer
20537#endif
20538)
Atul Mittal115287b2014-07-08 13:26:33 +053020539{
20540
20541 hddTdlsPeer_t *pTdlsPeer;
20542 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020543
Atul Mittal115287b2014-07-08 13:26:33 +053020544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20545 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20546 __func__, MAC_ADDR_ARRAY(peer));
20547
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020548 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20550 return -EINVAL;
20551 }
20552
Atul Mittal115287b2014-07-08 13:26:33 +053020553 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20554 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20555
20556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020557 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20558 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20559 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020560 return -ENOTSUPP;
20561 }
20562
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020563 mutex_lock(&pHddCtx->tdls_lock);
20564 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020565
20566 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020567 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020569 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020570 __func__, MAC_ADDR_ARRAY(peer));
20571 return -EINVAL;
20572 }
20573 else {
20574 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20575 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020576 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20577 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020578 /* if channel switch is configured, reset
20579 the channel for this peer */
20580 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20581 {
20582 pTdlsPeer->peerParams.channel = 0;
20583 pTdlsPeer->isOffChannelConfigured = FALSE;
20584 }
Atul Mittal115287b2014-07-08 13:26:33 +053020585 }
20586
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020587 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020588 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020590 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020591 }
Atul Mittal115287b2014-07-08 13:26:33 +053020592
20593 /*EXT TDLS*/
20594
20595 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020596 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20598 " %s TDLS set callback Failed",
20599 __func__);
20600 return -EINVAL;
20601 }
Atul Mittal115287b2014-07-08 13:26:33 +053020602
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020603 mutex_unlock(&pHddCtx->tdls_lock);
20604
20605 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020606}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020607static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20609 const u8 *peer,
20610#else
20611 u8 *peer,
20612#endif
20613 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020614{
20615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20616 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020617 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020618 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020620 ENTER();
20621
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020622 if (!pAdapter) {
20623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20624 return -EINVAL;
20625 }
20626
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020627 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20628 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20629 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020630 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020631 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020633 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020634 return -EINVAL;
20635 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020636
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020637 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020638 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020639 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020640 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020641 }
20642
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020643
20644 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020645 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020646 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020648 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20649 "Cannot process TDLS commands",
20650 pHddCtx->cfg_ini->fEnableTDLSSupport,
20651 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020652 return -ENOTSUPP;
20653 }
20654
20655 switch (oper) {
20656 case NL80211_TDLS_ENABLE_LINK:
20657 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020658 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020659 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020660 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20661 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020662 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020663 tANI_U16 numCurrTdlsPeers = 0;
20664 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020665 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020666 tSirMacAddr peerMac;
20667 int channel;
20668 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020669
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20671 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20672 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020673
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020674 mutex_lock(&pHddCtx->tdls_lock);
20675 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020676 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020677 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020678 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20680 " (oper %d) not exsting. ignored",
20681 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20682 return -EINVAL;
20683 }
20684
20685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20686 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20687 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20688 "NL80211_TDLS_ENABLE_LINK");
20689
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020690 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20691 {
20692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20693 MAC_ADDRESS_STR " failed",
20694 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020695 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020696 return -EINVAL;
20697 }
20698
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020699 /* before starting tdls connection, set tdls
20700 * off channel established status to default value */
20701 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020702
20703 mutex_unlock(&pHddCtx->tdls_lock);
20704
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020705 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020706 /* TDLS Off Channel, Disable tdls channel switch,
20707 when there are more than one tdls link */
20708 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020709 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020710 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020711 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020712 /* get connected peer and send disable tdls off chan */
20713 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020714 if ((connPeer) &&
20715 (connPeer->isOffChannelSupported == TRUE) &&
20716 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020717 {
20718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20719 "%s: More then one peer connected, Disable "
20720 "TDLS channel switch", __func__);
20721
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020722 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020723 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20724 channel = connPeer->peerParams.channel;
20725
20726 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020727
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020728 ret = sme_SendTdlsChanSwitchReq(
20729 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020730 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020731 peerMac,
20732 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020733 TDLS_OFF_CHANNEL_BW_OFFSET,
20734 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020735 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020736 hddLog(VOS_TRACE_LEVEL_ERROR,
20737 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020738 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020739 }
20740 else
20741 {
20742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20743 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020744 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020745 "isOffChannelConfigured %d",
20746 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020747 (connPeer ? (connPeer->isOffChannelSupported)
20748 : -1),
20749 (connPeer ? (connPeer->isOffChannelConfigured)
20750 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020751 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020752 }
20753 }
20754
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020755 mutex_lock(&pHddCtx->tdls_lock);
20756 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20757 if ( NULL == pTdlsPeer ) {
20758 mutex_unlock(&pHddCtx->tdls_lock);
20759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20760 "%s: " MAC_ADDRESS_STR
20761 " (oper %d) peer got freed in other context. ignored",
20762 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20763 return -EINVAL;
20764 }
20765 peer_status = pTdlsPeer->link_status;
20766 mutex_unlock(&pHddCtx->tdls_lock);
20767
20768 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020769 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020770 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020771
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020772 if (0 != wlan_hdd_tdls_get_link_establish_params(
20773 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020775 return -EINVAL;
20776 }
20777 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020778
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020779 ret = sme_SendTdlsLinkEstablishParams(
20780 WLAN_HDD_GET_HAL_CTX(pAdapter),
20781 pAdapter->sessionId, peer,
20782 &tdlsLinkEstablishParams);
20783 if (ret != VOS_STATUS_SUCCESS) {
20784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20785 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020786 /* Send TDLS peer UAPSD capabilities to the firmware and
20787 * register with the TL on after the response for this operation
20788 * is received .
20789 */
20790 ret = wait_for_completion_interruptible_timeout(
20791 &pAdapter->tdls_link_establish_req_comp,
20792 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020793
20794 mutex_lock(&pHddCtx->tdls_lock);
20795 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20796 if ( NULL == pTdlsPeer ) {
20797 mutex_unlock(&pHddCtx->tdls_lock);
20798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20799 "%s %d: " MAC_ADDRESS_STR
20800 " (oper %d) peer got freed in other context. ignored",
20801 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20802 (int)oper);
20803 return -EINVAL;
20804 }
20805 peer_status = pTdlsPeer->link_status;
20806 mutex_unlock(&pHddCtx->tdls_lock);
20807
20808 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020809 {
20810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020811 FL("Link Establish Request Failed Status %ld"),
20812 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020813 return -EINVAL;
20814 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020815 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020816
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020817 mutex_lock(&pHddCtx->tdls_lock);
20818 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20819 if ( NULL == pTdlsPeer ) {
20820 mutex_unlock(&pHddCtx->tdls_lock);
20821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20822 "%s: " MAC_ADDRESS_STR
20823 " (oper %d) peer got freed in other context. ignored",
20824 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20825 return -EINVAL;
20826 }
20827
Atul Mittal115287b2014-07-08 13:26:33 +053020828 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20829 eTDLS_LINK_CONNECTED,
20830 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020831 staDesc.ucSTAId = pTdlsPeer->staId;
20832 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020833
20834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20835 "%s: tdlsLinkEstablishParams of peer "
20836 MAC_ADDRESS_STR "uapsdQueues: %d"
20837 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20838 "isResponder: %d peerstaId: %d",
20839 __func__,
20840 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20841 tdlsLinkEstablishParams.uapsdQueues,
20842 tdlsLinkEstablishParams.qos,
20843 tdlsLinkEstablishParams.maxSp,
20844 tdlsLinkEstablishParams.isBufSta,
20845 tdlsLinkEstablishParams.isOffChannelSupported,
20846 tdlsLinkEstablishParams.isResponder,
20847 pTdlsPeer->staId);
20848
20849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20850 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20851 __func__,
20852 staDesc.ucSTAId,
20853 staDesc.ucQosEnabled);
20854
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020855 ret = WLANTL_UpdateTdlsSTAClient(
20856 pHddCtx->pvosContext,
20857 &staDesc);
20858 if (ret != VOS_STATUS_SUCCESS) {
20859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20860 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020861
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020862 /* Mark TDLS client Authenticated .*/
20863 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20864 pTdlsPeer->staId,
20865 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020866 if (VOS_STATUS_SUCCESS == status)
20867 {
Hoonki Lee14621352013-04-16 17:51:19 -070020868 if (pTdlsPeer->is_responder == 0)
20869 {
20870 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020871 tdlsConnInfo_t *tdlsInfo;
20872
20873 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20874
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020875 if (!vos_timer_is_initialized(
20876 &pTdlsPeer->initiatorWaitTimeoutTimer))
20877 {
20878 /* Initialize initiator wait callback */
20879 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020880 &pTdlsPeer->initiatorWaitTimeoutTimer,
20881 VOS_TIMER_TYPE_SW,
20882 wlan_hdd_tdls_initiator_wait_cb,
20883 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020884 }
Hoonki Lee14621352013-04-16 17:51:19 -070020885 wlan_hdd_tdls_timer_restart(pAdapter,
20886 &pTdlsPeer->initiatorWaitTimeoutTimer,
20887 WAIT_TIME_TDLS_INITIATOR);
20888 /* suspend initiator TX until it receives direct packet from the
20889 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020890 ret = WLANTL_SuspendDataTx(
20891 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20892 &staId, NULL);
20893 if (ret != VOS_STATUS_SUCCESS) {
20894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20895 }
Hoonki Lee14621352013-04-16 17:51:19 -070020896 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020897
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020898 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020899 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020900 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020901 suppChannelLen =
20902 tdlsLinkEstablishParams.supportedChannelsLen;
20903
20904 if ((suppChannelLen > 0) &&
20905 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20906 {
20907 tANI_U8 suppPeerChannel = 0;
20908 int i = 0;
20909 for (i = 0U; i < suppChannelLen; i++)
20910 {
20911 suppPeerChannel =
20912 tdlsLinkEstablishParams.supportedChannels[i];
20913
20914 pTdlsPeer->isOffChannelSupported = FALSE;
20915 if (suppPeerChannel ==
20916 pTdlsPeer->peerParams.channel)
20917 {
20918 pTdlsPeer->isOffChannelSupported = TRUE;
20919 break;
20920 }
20921 }
20922 }
20923 else
20924 {
20925 pTdlsPeer->isOffChannelSupported = FALSE;
20926 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020927 }
20928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20929 "%s: TDLS channel switch request for channel "
20930 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020931 "%d isOffChannelSupported %d", __func__,
20932 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020933 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020934 suppChannelLen,
20935 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020936
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020937 /* TDLS Off Channel, Enable tdls channel switch,
20938 when their is only one tdls link and it supports */
20939 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20940 if ((numCurrTdlsPeers == 1) &&
20941 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20942 (TRUE == pTdlsPeer->isOffChannelConfigured))
20943 {
20944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20945 "%s: Send TDLS channel switch request for channel %d",
20946 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020947
20948 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020949 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20950 channel = pTdlsPeer->peerParams.channel;
20951
20952 mutex_unlock(&pHddCtx->tdls_lock);
20953
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020954 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20955 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020956 peerMac,
20957 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020958 TDLS_OFF_CHANNEL_BW_OFFSET,
20959 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020960 if (ret != VOS_STATUS_SUCCESS) {
20961 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20962 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020963 }
20964 else
20965 {
20966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20967 "%s: TDLS channel switch request not sent"
20968 " numCurrTdlsPeers %d "
20969 "isOffChannelSupported %d "
20970 "isOffChannelConfigured %d",
20971 __func__, numCurrTdlsPeers,
20972 pTdlsPeer->isOffChannelSupported,
20973 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020974 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020975 }
20976
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020977 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020978 else
20979 mutex_unlock(&pHddCtx->tdls_lock);
20980
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020981 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020982
20983 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020984 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20985 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020986 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020987 int ac;
20988 uint8 ucAc[4] = { WLANTL_AC_VO,
20989 WLANTL_AC_VI,
20990 WLANTL_AC_BK,
20991 WLANTL_AC_BE };
20992 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20993 for(ac=0; ac < 4; ac++)
20994 {
20995 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20996 pTdlsPeer->staId, ucAc[ac],
20997 tlTid[ac], tlTid[ac], 0, 0,
20998 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020999 if (status != VOS_STATUS_SUCCESS) {
21000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21001 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021002 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021003 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021004 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021005
Bhargav Shah66896792015-10-01 18:17:37 +053021006 /* stop TCP delack timer if TDLS is enable */
21007 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21008 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021009 hdd_wlan_tdls_enable_link_event(peer,
21010 pTdlsPeer->isOffChannelSupported,
21011 pTdlsPeer->isOffChannelConfigured,
21012 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021013 }
21014 break;
21015 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021016 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021017 tANI_U16 numCurrTdlsPeers = 0;
21018 hddTdlsPeer_t *connPeer = NULL;
21019
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21021 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21022 __func__, MAC_ADDR_ARRAY(peer));
21023
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021024 mutex_lock(&pHddCtx->tdls_lock);
21025 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021026
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021027
Sunil Dutt41de4e22013-11-14 18:09:02 +053021028 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021029 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21031 " (oper %d) not exsting. ignored",
21032 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21033 return -EINVAL;
21034 }
21035
21036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21037 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21038 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21039 "NL80211_TDLS_DISABLE_LINK");
21040
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021041 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021042 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021043 long status;
21044
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021045 /* set tdls off channel status to false for this peer */
21046 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021047 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21048 eTDLS_LINK_TEARING,
21049 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21050 eTDLS_LINK_UNSPECIFIED:
21051 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021052 mutex_unlock(&pHddCtx->tdls_lock);
21053
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021054 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21055
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021056 status = sme_DeleteTdlsPeerSta(
21057 WLAN_HDD_GET_HAL_CTX(pAdapter),
21058 pAdapter->sessionId, peer );
21059 if (status != VOS_STATUS_SUCCESS) {
21060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21061 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021062
21063 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21064 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021065
21066 mutex_lock(&pHddCtx->tdls_lock);
21067 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21068 if ( NULL == pTdlsPeer ) {
21069 mutex_unlock(&pHddCtx->tdls_lock);
21070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21071 " peer was freed in other context",
21072 __func__, MAC_ADDR_ARRAY(peer));
21073 return -EINVAL;
21074 }
21075
Atul Mittal271a7652014-09-12 13:18:22 +053021076 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021077 eTDLS_LINK_IDLE,
21078 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021079 mutex_unlock(&pHddCtx->tdls_lock);
21080
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021081 if (status <= 0)
21082 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21084 "%s: Del station failed status %ld",
21085 __func__, status);
21086 return -EPERM;
21087 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021088
21089 /* TDLS Off Channel, Enable tdls channel switch,
21090 when their is only one tdls link and it supports */
21091 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21092 if (numCurrTdlsPeers == 1)
21093 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021094 tSirMacAddr peerMac;
21095 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021096
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021097 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021098 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021099
21100 if (connPeer == NULL) {
21101 mutex_unlock(&pHddCtx->tdls_lock);
21102 hddLog(VOS_TRACE_LEVEL_ERROR,
21103 "%s connPeer is NULL", __func__);
21104 return -EINVAL;
21105 }
21106
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021107 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21108 channel = connPeer->peerParams.channel;
21109
21110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21111 "%s: TDLS channel switch "
21112 "isOffChannelSupported %d "
21113 "isOffChannelConfigured %d "
21114 "isOffChannelEstablished %d",
21115 __func__,
21116 (connPeer ? connPeer->isOffChannelSupported : -1),
21117 (connPeer ? connPeer->isOffChannelConfigured : -1),
21118 (connPeer ? connPeer->isOffChannelEstablished : -1));
21119
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021120 if ((connPeer) &&
21121 (connPeer->isOffChannelSupported == TRUE) &&
21122 (connPeer->isOffChannelConfigured == TRUE))
21123 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021124 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021125 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021126 status = sme_SendTdlsChanSwitchReq(
21127 WLAN_HDD_GET_HAL_CTX(pAdapter),
21128 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021129 peerMac,
21130 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021131 TDLS_OFF_CHANNEL_BW_OFFSET,
21132 TDLS_CHANNEL_SWITCH_ENABLE);
21133 if (status != VOS_STATUS_SUCCESS) {
21134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21135 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021136 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021137 else
21138 mutex_unlock(&pHddCtx->tdls_lock);
21139 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021140 else
21141 {
21142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21143 "%s: TDLS channel switch request not sent "
21144 "numCurrTdlsPeers %d ",
21145 __func__, numCurrTdlsPeers);
21146 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021147 }
21148 else
21149 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021150 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21152 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021153 }
Bhargav Shah66896792015-10-01 18:17:37 +053021154 if (numCurrTdlsPeers == 0) {
21155 /* start TCP delack timer if TDLS is disable */
21156 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21157 hdd_manage_delack_timer(pHddCtx);
21158 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021159 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021160 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021161 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021162 {
Atul Mittal115287b2014-07-08 13:26:33 +053021163 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021164
Atul Mittal115287b2014-07-08 13:26:33 +053021165 if (0 != status)
21166 {
21167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021168 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021169 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021170 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021171 break;
21172 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021173 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021174 {
Atul Mittal115287b2014-07-08 13:26:33 +053021175 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21176 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021177 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021178 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021179
Atul Mittal115287b2014-07-08 13:26:33 +053021180 if (0 != status)
21181 {
21182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021183 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021184 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021185 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021186 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021187 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021188 case NL80211_TDLS_DISCOVERY_REQ:
21189 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021191 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021192 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021193 return -ENOTSUPP;
21194 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21196 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021197 return -ENOTSUPP;
21198 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021199
21200 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021201 return 0;
21202}
Chilam NG571c65a2013-01-19 12:27:36 +053021203
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021204static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021205#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21206 const u8 *peer,
21207#else
21208 u8 *peer,
21209#endif
21210 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021211{
21212 int ret;
21213
21214 vos_ssr_protect(__func__);
21215 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21216 vos_ssr_unprotect(__func__);
21217
21218 return ret;
21219}
21220
Chilam NG571c65a2013-01-19 12:27:36 +053021221int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21222 struct net_device *dev, u8 *peer)
21223{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021224 hddLog(VOS_TRACE_LEVEL_INFO,
21225 "tdls send discover req: "MAC_ADDRESS_STR,
21226 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021227#if TDLS_MGMT_VERSION2
21228 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21229 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21230#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21232 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21233 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21234#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21235 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21236 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21237#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21238 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21239 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21240#else
Chilam NG571c65a2013-01-19 12:27:36 +053021241 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21242 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021243#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021244#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021245}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021246#endif
21247
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021248#ifdef WLAN_FEATURE_GTK_OFFLOAD
21249/*
21250 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21251 * Callback rountine called upon receiving response for
21252 * get offload info
21253 */
21254void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21255 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21256{
21257
21258 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021259 tANI_U8 tempReplayCounter[8];
21260 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021261
21262 ENTER();
21263
21264 if (NULL == pAdapter)
21265 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021267 "%s: HDD adapter is Null", __func__);
21268 return ;
21269 }
21270
21271 if (NULL == pGtkOffloadGetInfoRsp)
21272 {
21273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21274 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21275 return ;
21276 }
21277
21278 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21279 {
21280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21281 "%s: wlan Failed to get replay counter value",
21282 __func__);
21283 return ;
21284 }
21285
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021286 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21287 /* Update replay counter */
21288 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21289 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21290
21291 {
21292 /* changing from little to big endian since supplicant
21293 * works on big endian format
21294 */
21295 int i;
21296 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21297
21298 for (i = 0; i < 8; i++)
21299 {
21300 tempReplayCounter[7-i] = (tANI_U8)p[i];
21301 }
21302 }
21303
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021304 /* Update replay counter to NL */
21305 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021306 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021307}
21308
21309/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021310 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021311 * This function is used to offload GTK rekeying job to the firmware.
21312 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021313int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021314 struct cfg80211_gtk_rekey_data *data)
21315{
21316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21317 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21318 hdd_station_ctx_t *pHddStaCtx;
21319 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021320 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021321 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021322 eHalStatus status = eHAL_STATUS_FAILURE;
21323
21324 ENTER();
21325
21326 if (NULL == pAdapter)
21327 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021329 "%s: HDD adapter is Null", __func__);
21330 return -ENODEV;
21331 }
21332
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021333 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21334 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21335 pAdapter->sessionId, pAdapter->device_mode));
21336
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021337 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021338 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021339 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021340 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021341 }
21342
21343 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21344 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21345 if (NULL == hHal)
21346 {
21347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21348 "%s: HAL context is Null!!!", __func__);
21349 return -EAGAIN;
21350 }
21351
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021352 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21353 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21354 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21355 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021356 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021357 {
21358 /* changing from big to little endian since driver
21359 * works on little endian format
21360 */
21361 tANI_U8 *p =
21362 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21363 int i;
21364
21365 for (i = 0; i < 8; i++)
21366 {
21367 p[7-i] = data->replay_ctr[i];
21368 }
21369 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021370
21371 if (TRUE == pHddCtx->hdd_wlan_suspended)
21372 {
21373 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021374 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21375 sizeof (tSirGtkOffloadParams));
21376 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021377 pAdapter->sessionId);
21378
21379 if (eHAL_STATUS_SUCCESS != status)
21380 {
21381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21382 "%s: sme_SetGTKOffload failed, returned %d",
21383 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021384
21385 /* Need to clear any trace of key value in the memory.
21386 * Thus zero out the memory even though it is local
21387 * variable.
21388 */
21389 vos_mem_zero(&hddGtkOffloadReqParams,
21390 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021391 return status;
21392 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21394 "%s: sme_SetGTKOffload successfull", __func__);
21395 }
21396 else
21397 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21399 "%s: wlan not suspended GTKOffload request is stored",
21400 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021401 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021402
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021403 /* Need to clear any trace of key value in the memory.
21404 * Thus zero out the memory even though it is local
21405 * variable.
21406 */
21407 vos_mem_zero(&hddGtkOffloadReqParams,
21408 sizeof(hddGtkOffloadReqParams));
21409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021410 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021411 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021412}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021413
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021414int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21415 struct cfg80211_gtk_rekey_data *data)
21416{
21417 int ret;
21418
21419 vos_ssr_protect(__func__);
21420 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21421 vos_ssr_unprotect(__func__);
21422
21423 return ret;
21424}
21425#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021426/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021427 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021428 * This function is used to set access control policy
21429 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021430static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21431 struct net_device *dev,
21432 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021433{
21434 int i;
21435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21436 hdd_hostapd_state_t *pHostapdState;
21437 tsap_Config_t *pConfig;
21438 v_CONTEXT_t pVosContext = NULL;
21439 hdd_context_t *pHddCtx;
21440 int status;
21441
21442 ENTER();
21443
21444 if (NULL == pAdapter)
21445 {
21446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21447 "%s: HDD adapter is Null", __func__);
21448 return -ENODEV;
21449 }
21450
21451 if (NULL == params)
21452 {
21453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21454 "%s: params is Null", __func__);
21455 return -EINVAL;
21456 }
21457
21458 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21459 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021460 if (0 != status)
21461 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021462 return status;
21463 }
21464
21465 pVosContext = pHddCtx->pvosContext;
21466 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21467
21468 if (NULL == pHostapdState)
21469 {
21470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21471 "%s: pHostapdState is Null", __func__);
21472 return -EINVAL;
21473 }
21474
21475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21476 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21478 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21479 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021480
21481 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21482 {
21483 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21484
21485 /* default value */
21486 pConfig->num_accept_mac = 0;
21487 pConfig->num_deny_mac = 0;
21488
21489 /**
21490 * access control policy
21491 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21492 * listed in hostapd.deny file.
21493 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21494 * listed in hostapd.accept file.
21495 */
21496 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21497 {
21498 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21499 }
21500 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21501 {
21502 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21503 }
21504 else
21505 {
21506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21507 "%s:Acl Policy : %d is not supported",
21508 __func__, params->acl_policy);
21509 return -ENOTSUPP;
21510 }
21511
21512 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21513 {
21514 pConfig->num_accept_mac = params->n_acl_entries;
21515 for (i = 0; i < params->n_acl_entries; i++)
21516 {
21517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21518 "** Add ACL MAC entry %i in WhiletList :"
21519 MAC_ADDRESS_STR, i,
21520 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21521
21522 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21523 sizeof(qcmacaddr));
21524 }
21525 }
21526 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21527 {
21528 pConfig->num_deny_mac = params->n_acl_entries;
21529 for (i = 0; i < params->n_acl_entries; i++)
21530 {
21531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21532 "** Add ACL MAC entry %i in BlackList :"
21533 MAC_ADDRESS_STR, i,
21534 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21535
21536 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21537 sizeof(qcmacaddr));
21538 }
21539 }
21540
21541 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21542 {
21543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21544 "%s: SAP Set Mac Acl fail", __func__);
21545 return -EINVAL;
21546 }
21547 }
21548 else
21549 {
21550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021551 "%s: Invalid device_mode = %s (%d)",
21552 __func__, hdd_device_modetoString(pAdapter->device_mode),
21553 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021554 return -EINVAL;
21555 }
21556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021557 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021558 return 0;
21559}
21560
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021561static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21562 struct net_device *dev,
21563 const struct cfg80211_acl_data *params)
21564{
21565 int ret;
21566 vos_ssr_protect(__func__);
21567 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21568 vos_ssr_unprotect(__func__);
21569
21570 return ret;
21571}
21572
Leo Chang9056f462013-08-01 19:21:11 -070021573#ifdef WLAN_NL80211_TESTMODE
21574#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021575void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021576(
21577 void *pAdapter,
21578 void *indCont
21579)
21580{
Leo Changd9df8aa2013-09-26 13:32:26 -070021581 tSirLPHBInd *lphbInd;
21582 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021583 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021584
21585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021586 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021587
c_hpothu73f35e62014-04-18 13:40:08 +053021588 if (pAdapter == NULL)
21589 {
21590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21591 "%s: pAdapter is NULL\n",__func__);
21592 return;
21593 }
21594
Leo Chang9056f462013-08-01 19:21:11 -070021595 if (NULL == indCont)
21596 {
21597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021598 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021599 return;
21600 }
21601
c_hpothu73f35e62014-04-18 13:40:08 +053021602 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021603 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021604 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021605 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021606 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021607 GFP_ATOMIC);
21608 if (!skb)
21609 {
21610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21611 "LPHB timeout, NL buffer alloc fail");
21612 return;
21613 }
21614
Leo Changac3ba772013-10-07 09:47:04 -070021615 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021616 {
21617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21618 "WLAN_HDD_TM_ATTR_CMD put fail");
21619 goto nla_put_failure;
21620 }
Leo Changac3ba772013-10-07 09:47:04 -070021621 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021622 {
21623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21624 "WLAN_HDD_TM_ATTR_TYPE put fail");
21625 goto nla_put_failure;
21626 }
Leo Changac3ba772013-10-07 09:47:04 -070021627 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021628 sizeof(tSirLPHBInd), lphbInd))
21629 {
21630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21631 "WLAN_HDD_TM_ATTR_DATA put fail");
21632 goto nla_put_failure;
21633 }
Leo Chang9056f462013-08-01 19:21:11 -070021634 cfg80211_testmode_event(skb, GFP_ATOMIC);
21635 return;
21636
21637nla_put_failure:
21638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21639 "NLA Put fail");
21640 kfree_skb(skb);
21641
21642 return;
21643}
21644#endif /* FEATURE_WLAN_LPHB */
21645
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021646static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021647{
21648 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21649 int err = 0;
21650#ifdef FEATURE_WLAN_LPHB
21651 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021652 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021653
21654 ENTER();
21655
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021656 err = wlan_hdd_validate_context(pHddCtx);
21657 if (0 != err)
21658 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021659 return err;
21660 }
Leo Chang9056f462013-08-01 19:21:11 -070021661#endif /* FEATURE_WLAN_LPHB */
21662
21663 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21664 if (err)
21665 {
21666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21667 "%s Testmode INV ATTR", __func__);
21668 return err;
21669 }
21670
21671 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21672 {
21673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21674 "%s Testmode INV CMD", __func__);
21675 return -EINVAL;
21676 }
21677
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021678 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21679 TRACE_CODE_HDD_CFG80211_TESTMODE,
21680 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021681 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21682 {
21683#ifdef FEATURE_WLAN_LPHB
21684 /* Low Power Heartbeat configuration request */
21685 case WLAN_HDD_TM_CMD_WLAN_HB:
21686 {
21687 int buf_len;
21688 void *buf;
21689 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021690 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021691
21692 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21693 {
21694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21695 "%s Testmode INV DATA", __func__);
21696 return -EINVAL;
21697 }
21698
21699 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21700 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021701
Manjeet Singh3c577442017-02-10 19:03:38 +053021702 if (buf_len > sizeof(*hb_params)) {
21703 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21704 buf_len);
21705 return -ERANGE;
21706 }
21707
Amar Singhal05852702014-02-04 14:40:00 -080021708 hb_params_temp =(tSirLPHBReq *)buf;
21709 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21710 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21711 return -EINVAL;
21712
Leo Chang9056f462013-08-01 19:21:11 -070021713 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21714 if (NULL == hb_params)
21715 {
21716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21717 "%s Request Buffer Alloc Fail", __func__);
21718 return -EINVAL;
21719 }
21720
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021721 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021722 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021723 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21724 hb_params,
21725 wlan_hdd_cfg80211_lphb_ind_handler);
21726 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021727 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21729 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021730 vos_mem_free(hb_params);
21731 }
Leo Chang9056f462013-08-01 19:21:11 -070021732 return 0;
21733 }
21734#endif /* FEATURE_WLAN_LPHB */
21735 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21737 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021738 return -EOPNOTSUPP;
21739 }
21740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021741 EXIT();
21742 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021743}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021744
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021745static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21747 struct wireless_dev *wdev,
21748#endif
21749 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021750{
21751 int ret;
21752
21753 vos_ssr_protect(__func__);
21754 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21755 vos_ssr_unprotect(__func__);
21756
21757 return ret;
21758}
Leo Chang9056f462013-08-01 19:21:11 -070021759#endif /* CONFIG_NL80211_TESTMODE */
21760
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021761extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021762static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021763 struct net_device *dev,
21764 int idx, struct survey_info *survey)
21765{
21766 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21767 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021768 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021769 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021770 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021771 v_S7_t snr,rssi;
21772 int status, i, j, filled = 0;
21773
21774 ENTER();
21775
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021776 if (NULL == pAdapter)
21777 {
21778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21779 "%s: HDD adapter is Null", __func__);
21780 return -ENODEV;
21781 }
21782
21783 if (NULL == wiphy)
21784 {
21785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21786 "%s: wiphy is Null", __func__);
21787 return -ENODEV;
21788 }
21789
21790 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21791 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021792 if (0 != status)
21793 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021794 return status;
21795 }
21796
Mihir Sheted9072e02013-08-21 17:02:29 +053021797 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21798
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021799 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021800 0 != pAdapter->survey_idx ||
21801 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021802 {
21803 /* The survey dump ops when implemented completely is expected to
21804 * return a survey of all channels and the ops is called by the
21805 * kernel with incremental values of the argument 'idx' till it
21806 * returns -ENONET. But we can only support the survey for the
21807 * operating channel for now. survey_idx is used to track
21808 * that the ops is called only once and then return -ENONET for
21809 * the next iteration
21810 */
21811 pAdapter->survey_idx = 0;
21812 return -ENONET;
21813 }
21814
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021815 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21816 {
21817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21818 "%s: Roaming in progress, hence return ", __func__);
21819 return -ENONET;
21820 }
21821
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021822 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21823
21824 wlan_hdd_get_snr(pAdapter, &snr);
21825 wlan_hdd_get_rssi(pAdapter, &rssi);
21826
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021827 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21828 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21829 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021830 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21831 hdd_wlan_get_freq(channel, &freq);
21832
21833
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021834 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021835 {
21836 if (NULL == wiphy->bands[i])
21837 {
21838 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21839 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21840 continue;
21841 }
21842
21843 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21844 {
21845 struct ieee80211_supported_band *band = wiphy->bands[i];
21846
21847 if (band->channels[j].center_freq == (v_U16_t)freq)
21848 {
21849 survey->channel = &band->channels[j];
21850 /* The Rx BDs contain SNR values in dB for the received frames
21851 * while the supplicant expects noise. So we calculate and
21852 * return the value of noise (dBm)
21853 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21854 */
21855 survey->noise = rssi - snr;
21856 survey->filled = SURVEY_INFO_NOISE_DBM;
21857 filled = 1;
21858 }
21859 }
21860 }
21861
21862 if (filled)
21863 pAdapter->survey_idx = 1;
21864 else
21865 {
21866 pAdapter->survey_idx = 0;
21867 return -ENONET;
21868 }
21869
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021870 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021871 return 0;
21872}
21873
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021874static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21875 struct net_device *dev,
21876 int idx, struct survey_info *survey)
21877{
21878 int ret;
21879
21880 vos_ssr_protect(__func__);
21881 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21882 vos_ssr_unprotect(__func__);
21883
21884 return ret;
21885}
21886
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021887/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021888 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021889 * this is called when cfg80211 driver resume
21890 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21891 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021892int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021893{
21894 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21895 hdd_adapter_t *pAdapter;
21896 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21897 VOS_STATUS status = VOS_STATUS_SUCCESS;
21898
21899 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021900
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021901 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021902 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021903 return 0;
21904 }
21905
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021906 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21907 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021908
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021909 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021910 {
21911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21912 "%s: Resume SoftAP", __func__);
21913 hdd_set_wlan_suspend_mode(false);
21914 }
21915
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021916 spin_lock(&pHddCtx->schedScan_lock);
21917 pHddCtx->isWiphySuspended = FALSE;
21918 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21919 {
21920 spin_unlock(&pHddCtx->schedScan_lock);
21921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21922 "%s: Return resume is not due to PNO indication", __func__);
21923 return 0;
21924 }
21925 // Reset flag to avoid updatating cfg80211 data old results again
21926 pHddCtx->isSchedScanUpdatePending = FALSE;
21927 spin_unlock(&pHddCtx->schedScan_lock);
21928
21929 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21930
21931 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21932 {
21933 pAdapter = pAdapterNode->pAdapter;
21934 if ( (NULL != pAdapter) &&
21935 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21936 {
21937 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021938 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21940 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021941 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021942 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021943 {
21944 /* Acquire wakelock to handle the case where APP's tries to
21945 * suspend immediately after updating the scan results. Whis
21946 * results in app's is in suspended state and not able to
21947 * process the connect request to AP
21948 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021949 hdd_prevent_suspend_timeout(2000,
21950 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021951 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021952 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021953
21954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21955 "%s : cfg80211 scan result database updated", __func__);
21956
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021957 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021958 return 0;
21959
21960 }
21961 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21962 pAdapterNode = pNext;
21963 }
21964
21965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21966 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021967 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021968 return 0;
21969}
21970
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021971int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21972{
21973 int ret;
21974
21975 vos_ssr_protect(__func__);
21976 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21977 vos_ssr_unprotect(__func__);
21978
21979 return ret;
21980}
21981
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021982/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021983 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021984 * this is called when cfg80211 driver suspends
21985 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021986int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021987 struct cfg80211_wowlan *wow)
21988{
21989 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021990 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021991
21992 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021993
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021994 ret = wlan_hdd_validate_context(pHddCtx);
21995 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021996 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021997 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021998 }
21999
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022000 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22002 "%s: Suspend SoftAP", __func__);
22003 hdd_set_wlan_suspend_mode(true);
22004 }
22005
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022006
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022007 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22008 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22009 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022010 pHddCtx->isWiphySuspended = TRUE;
22011
22012 EXIT();
22013
22014 return 0;
22015}
22016
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022017int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22018 struct cfg80211_wowlan *wow)
22019{
22020 int ret;
22021
22022 vos_ssr_protect(__func__);
22023 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22024 vos_ssr_unprotect(__func__);
22025
22026 return ret;
22027}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022028
22029#ifdef FEATURE_OEM_DATA_SUPPORT
22030static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022031 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022032{
22033 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22034
22035 ENTER();
22036
22037 if (wlan_hdd_validate_context(pHddCtx)) {
22038 return;
22039 }
22040 if (!pMsg)
22041 {
22042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22043 return;
22044 }
22045
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022046 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022047
22048 EXIT();
22049 return;
22050
22051}
22052
22053void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022054 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022055{
22056 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22057
22058 ENTER();
22059
22060 if (wlan_hdd_validate_context(pHddCtx)) {
22061 return;
22062 }
22063
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022064 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022065
22066 switch(evType) {
22067 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022068 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022069 break;
22070 default:
22071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22072 break;
22073 }
22074 EXIT();
22075}
22076#endif
22077
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22079 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022080/**
22081 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22082 * @wiphy: Pointer to wiphy
22083 * @wdev: Pointer to wireless device structure
22084 *
22085 * This function is used to abort an ongoing scan
22086 *
22087 * Return: None
22088 */
22089static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22090 struct wireless_dev *wdev)
22091{
22092 struct net_device *dev = wdev->netdev;
22093 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22094 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22095 int ret;
22096
22097 ENTER();
22098
22099 if (NULL == adapter) {
22100 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22101 return;
22102 }
22103
22104 ret = wlan_hdd_validate_context(hdd_ctx);
22105 if (0 != ret)
22106 return;
22107
22108 wlan_hdd_scan_abort(adapter);
22109
22110 return;
22111}
22112
22113/**
22114 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22115 * @wiphy: Pointer to wiphy
22116 * @wdev: Pointer to wireless device structure
22117 *
22118 * Return: None
22119 */
22120void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22121 struct wireless_dev *wdev)
22122{
22123 vos_ssr_protect(__func__);
22124 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22125 vos_ssr_unprotect(__func__);
22126
22127 return;
22128}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022129#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022130
Abhishek Singh936c6932017-11-07 17:28:23 +053022131#ifdef CHANNEL_SWITCH_SUPPORTED
22132/**
22133 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22134 * channel in SAP/GO
22135 * @wiphy: wiphy pointer
22136 * @dev: dev pointer.
22137 * @csa_params: Change channel params
22138 *
22139 * This function is called to switch channel in SAP/GO
22140 *
22141 * Return: 0 if success else return non zero
22142 */
22143static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22144 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22145{
22146 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22147 hdd_context_t *hdd_ctx;
22148 uint8_t channel;
22149 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022150 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022151 v_CONTEXT_t vos_ctx;
22152
22153 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22154
22155 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22156 ret = wlan_hdd_validate_context(hdd_ctx);
22157 if (ret)
22158 return ret;
22159
22160 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22161 if (!vos_ctx) {
22162 hddLog(LOGE, FL("Vos ctx is null"));
22163 return -EINVAL;
22164 }
22165
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022166 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022167 return -ENOTSUPP;
22168
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022169 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22170 if (!sap_ctx) {
22171 hddLog(LOGE, FL("sap_ctx is NULL"));
22172 return -EINVAL;
22173 }
22174
22175 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22176 if (ret)
22177 return ret;
22178
22179 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22180
Abhishek Singh936c6932017-11-07 17:28:23 +053022181 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022182 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022183
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022184 if (ret) {
22185 wlansap_reset_chan_change_in_progress(sap_ctx);
22186 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22187 }
22188
Abhishek Singh936c6932017-11-07 17:28:23 +053022189 return ret;
22190}
22191
22192/**
22193 * wlan_hdd_cfg80211_channel_switch()- function to switch
22194 * channel in SAP/GO
22195 * @wiphy: wiphy pointer
22196 * @dev: dev pointer.
22197 * @csa_params: Change channel params
22198 *
22199 * This function is called to switch channel in SAP/GO
22200 *
22201 * Return: 0 if success else return non zero
22202 */
22203static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22204 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22205{
22206 int ret;
22207
22208 vos_ssr_protect(__func__);
22209 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22210 vos_ssr_unprotect(__func__);
22211
22212 return ret;
22213}
22214#endif
22215
Jeff Johnson295189b2012-06-20 16:38:30 -070022216/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022217static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022218{
22219 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22220 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22221 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22222 .change_station = wlan_hdd_change_station,
22223#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22224 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22225 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22226 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022227#else
22228 .start_ap = wlan_hdd_cfg80211_start_ap,
22229 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22230 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022231#endif
22232 .change_bss = wlan_hdd_cfg80211_change_bss,
22233 .add_key = wlan_hdd_cfg80211_add_key,
22234 .get_key = wlan_hdd_cfg80211_get_key,
22235 .del_key = wlan_hdd_cfg80211_del_key,
22236 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022237#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022238 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022239#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022240 .scan = wlan_hdd_cfg80211_scan,
22241 .connect = wlan_hdd_cfg80211_connect,
22242 .disconnect = wlan_hdd_cfg80211_disconnect,
22243 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22244 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22245 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22246 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22247 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022248 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22249 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022250 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022251#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22252 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22253 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22254 .set_txq_params = wlan_hdd_set_txq_params,
22255#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022256 .get_station = wlan_hdd_cfg80211_get_station,
22257 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22258 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022259 .add_station = wlan_hdd_cfg80211_add_station,
22260#ifdef FEATURE_WLAN_LFR
22261 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22262 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22263 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22264#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022265#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22266 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22267#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022268#ifdef FEATURE_WLAN_TDLS
22269 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22270 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22271#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022272#ifdef WLAN_FEATURE_GTK_OFFLOAD
22273 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22274#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022275#ifdef FEATURE_WLAN_SCAN_PNO
22276 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22277 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22278#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022279 .resume = wlan_hdd_cfg80211_resume_wlan,
22280 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022281 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022282#ifdef WLAN_NL80211_TESTMODE
22283 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22284#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022285 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22287 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022288 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022289#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022290#ifdef CHANNEL_SWITCH_SUPPORTED
22291 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22292#endif
22293
Jeff Johnson295189b2012-06-20 16:38:30 -070022294};
22295