blob: 35f2a8ec397ccdd3bb67c920491189758f8eac67 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
Abhinav Kumar1ac5cb42018-09-21 16:11:03 +0530307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
308 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
314};
315
Jeff Johnson295189b2012-06-20 16:38:30 -0700316static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
317{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530318 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530320 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 .bitrates = a_mode_rates,
322 .n_bitrates = a_mode_rates_size,
323 .ht_cap.ht_supported = 1,
324 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
325 | IEEE80211_HT_CAP_GRN_FLD
326 | IEEE80211_HT_CAP_DSSSCCK40
327 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
328 | IEEE80211_HT_CAP_SGI_40
329 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
330 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
331 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
332 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
333 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
334 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
335};
336
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530337/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 TX/RX direction for each kind of interface */
339static const struct ieee80211_txrx_stypes
340wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
341 [NL80211_IFTYPE_STATION] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ACTION) |
344 BIT(SIR_MAC_MGMT_PROBE_REQ),
345 },
346 [NL80211_IFTYPE_AP] = {
347 .tx = 0xffff,
348 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
350 BIT(SIR_MAC_MGMT_PROBE_REQ) |
351 BIT(SIR_MAC_MGMT_DISASSOC) |
352 BIT(SIR_MAC_MGMT_AUTH) |
353 BIT(SIR_MAC_MGMT_DEAUTH) |
354 BIT(SIR_MAC_MGMT_ACTION),
355 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700356 [NL80211_IFTYPE_ADHOC] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_PROBE_REQ) |
361 BIT(SIR_MAC_MGMT_DISASSOC) |
362 BIT(SIR_MAC_MGMT_AUTH) |
363 BIT(SIR_MAC_MGMT_DEAUTH) |
364 BIT(SIR_MAC_MGMT_ACTION),
365 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700366 [NL80211_IFTYPE_P2P_CLIENT] = {
367 .tx = 0xffff,
368 .rx = BIT(SIR_MAC_MGMT_ACTION) |
369 BIT(SIR_MAC_MGMT_PROBE_REQ),
370 },
371 [NL80211_IFTYPE_P2P_GO] = {
372 /* This is also same as for SoftAP */
373 .tx = 0xffff,
374 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ) |
377 BIT(SIR_MAC_MGMT_DISASSOC) |
378 BIT(SIR_MAC_MGMT_AUTH) |
379 BIT(SIR_MAC_MGMT_DEAUTH) |
380 BIT(SIR_MAC_MGMT_ACTION),
381 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700382};
383
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800385static const struct ieee80211_iface_limit
386wlan_hdd_iface_limit[] = {
387 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800388 /* max = 3 ; Our driver create two interfaces during driver init
389 * wlan0 and p2p0 interfaces. p2p0 is considered as station
390 * interface until a group is formed. In JB architecture, once the
391 * group is formed, interface type of p2p0 is changed to P2P GO or
392 * Client.
393 * When supplicant remove the group, it first issue a set interface
394 * cmd to change the mode back to Station. In JB this works fine as
395 * we advertize two station type interface during driver init.
396 * Some vendors create separate interface for P2P GO/Client,
397 * after group formation(Third one). But while group remove
398 * supplicant first tries to change the mode(3rd interface) to STATION
399 * But as we advertized only two sta type interfaces nl80211 was
400 * returning error for the third one which was leading to failure in
401 * delete interface. Ideally while removing the group, supplicant
402 * should not try to change the 3rd interface mode to Station type.
403 * Till we get a fix in wpa_supplicant, we advertize max STA
404 * interface type to 3
405 */
406 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800407 .types = BIT(NL80211_IFTYPE_STATION),
408 },
409 {
410 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700411 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800412 },
413 {
414 .max = 1,
415 .types = BIT(NL80211_IFTYPE_P2P_GO) |
416 BIT(NL80211_IFTYPE_P2P_CLIENT),
417 },
418};
419
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530420/* interface limits for sta + monitor SCC */
421static const struct ieee80211_iface_limit
422wlan_hdd_iface_sta_mon_limit[] = {
423 {
424 .max = 1,
425 .types = BIT(NL80211_IFTYPE_STATION),
426 },
427 {
428 .max = 1, /* Monitor interface */
429 .types = BIT(NL80211_IFTYPE_MONITOR),
430 },
431};
432
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800433/* By default, only single channel concurrency is allowed */
434static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530435wlan_hdd_iface_combination[] = {
436 {
437 .limits = wlan_hdd_iface_limit,
438 .num_different_channels = 1,
439 /*
440 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
441 * and p2p0 interfaces during driver init
442 * Some vendors create separate interface for P2P operations.
443 * wlan0: STA interface
444 * p2p0: P2P Device interface, action frames goes
445 * through this interface.
446 * p2p-xx: P2P interface, After GO negotiation this interface is
447 * created for p2p operations(GO/CLIENT interface).
448 */
449 .max_interfaces = WLAN_MAX_INTERFACES,
450 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
451 .beacon_int_infra_match = false,
452 },
453 {
454 .limits = wlan_hdd_iface_sta_mon_limit,
455 .num_different_channels = 1,
456 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
457 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
458 .beacon_int_infra_match = false,
459 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800460};
461#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800462
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530463#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
464static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +0530465 .flags = WIPHY_WOWLAN_ANY |
466 WIPHY_WOWLAN_MAGIC_PKT,
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530467 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
468 .pattern_min_len = 1,
469 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
470};
471#endif
472
Jeff Johnson295189b2012-06-20 16:38:30 -0700473static struct cfg80211_ops wlan_hdd_cfg80211_ops;
474
475/* Data rate 100KBPS based on IE Index */
476struct index_data_rate_type
477{
478 v_U8_t beacon_rate_index;
479 v_U16_t supported_rate[4];
480};
481
482/* 11B, 11G Rate table include Basic rate and Extended rate
483 The IDX field is the rate index
484 The HI field is the rate when RSSI is strong or being ignored
485 (in this case we report actual rate)
486 The MID field is the rate when RSSI is moderate
487 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
488 The LO field is the rate when RSSI is low
489 (in this case we don't report rates, actual current rate used)
490 */
491static const struct
492{
493 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700494 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700495} supported_data_rate[] =
496{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700497/* IDX HI HM LM LO (RSSI-based index */
498 {2, { 10, 10, 10, 0}},
499 {4, { 20, 20, 10, 0}},
500 {11, { 55, 20, 10, 0}},
501 {12, { 60, 55, 20, 0}},
502 {18, { 90, 55, 20, 0}},
503 {22, {110, 55, 20, 0}},
504 {24, {120, 90, 60, 0}},
505 {36, {180, 120, 60, 0}},
506 {44, {220, 180, 60, 0}},
507 {48, {240, 180, 90, 0}},
508 {66, {330, 180, 90, 0}},
509 {72, {360, 240, 90, 0}},
510 {96, {480, 240, 120, 0}},
511 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700512};
513
514/* MCS Based rate table */
515static struct index_data_rate_type supported_mcs_rate[] =
516{
517/* MCS L20 L40 S20 S40 */
518 {0, {65, 135, 72, 150}},
519 {1, {130, 270, 144, 300}},
520 {2, {195, 405, 217, 450}},
521 {3, {260, 540, 289, 600}},
522 {4, {390, 810, 433, 900}},
523 {5, {520, 1080, 578, 1200}},
524 {6, {585, 1215, 650, 1350}},
525 {7, {650, 1350, 722, 1500}}
526};
527
Leo Chang6f8870f2013-03-26 18:11:36 -0700528#ifdef WLAN_FEATURE_11AC
529
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530530#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700531
532struct index_vht_data_rate_type
533{
534 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530535 v_U16_t supported_VHT80_rate[2];
536 v_U16_t supported_VHT40_rate[2];
537 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700538};
539
540typedef enum
541{
542 DATA_RATE_11AC_MAX_MCS_7,
543 DATA_RATE_11AC_MAX_MCS_8,
544 DATA_RATE_11AC_MAX_MCS_9,
545 DATA_RATE_11AC_MAX_MCS_NA
546} eDataRate11ACMaxMcs;
547
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530548/* SSID broadcast type */
549typedef enum eSSIDBcastType
550{
551 eBCAST_UNKNOWN = 0,
552 eBCAST_NORMAL = 1,
553 eBCAST_HIDDEN = 2,
554} tSSIDBcastType;
555
Leo Chang6f8870f2013-03-26 18:11:36 -0700556/* MCS Based VHT rate table */
557static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
558{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530559/* MCS L80 S80 L40 S40 L20 S40*/
560 {0, {293, 325}, {135, 150}, {65, 72}},
561 {1, {585, 650}, {270, 300}, {130, 144}},
562 {2, {878, 975}, {405, 450}, {195, 217}},
563 {3, {1170, 1300}, {540, 600}, {260, 289}},
564 {4, {1755, 1950}, {810, 900}, {390, 433}},
565 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
566 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
567 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
568 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
569 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700570};
571#endif /* WLAN_FEATURE_11AC */
572
c_hpothu79aab322014-07-14 21:11:01 +0530573/*array index points to MCS and array value points respective rssi*/
574static int rssiMcsTbl[][10] =
575{
576/*MCS 0 1 2 3 4 5 6 7 8 9*/
577 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
578 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
579 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
580};
581
Jeff Johnson295189b2012-06-20 16:38:30 -0700582extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530583#ifdef FEATURE_WLAN_SCAN_PNO
584static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
585#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700586
Leo Chang9056f462013-08-01 19:21:11 -0700587#ifdef WLAN_NL80211_TESTMODE
588enum wlan_hdd_tm_attr
589{
590 WLAN_HDD_TM_ATTR_INVALID = 0,
591 WLAN_HDD_TM_ATTR_CMD = 1,
592 WLAN_HDD_TM_ATTR_DATA = 2,
593 WLAN_HDD_TM_ATTR_TYPE = 3,
594 /* keep last */
595 WLAN_HDD_TM_ATTR_AFTER_LAST,
596 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
597};
598
599enum wlan_hdd_tm_cmd
600{
601 WLAN_HDD_TM_CMD_WLAN_HB = 1,
602};
603
604#define WLAN_HDD_TM_DATA_MAX_LEN 5000
605
606static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
607{
608 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
609 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
610 .len = WLAN_HDD_TM_DATA_MAX_LEN },
611};
612#endif /* WLAN_NL80211_TESTMODE */
613
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800614#ifdef FEATURE_WLAN_CH_AVOID
615/*
616 * FUNCTION: wlan_hdd_send_avoid_freq_event
617 * This is called when wlan driver needs to send vendor specific
618 * avoid frequency range event to userspace
619 */
620int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
621 tHddAvoidFreqList *pAvoidFreqList)
622{
623 struct sk_buff *vendor_event;
624
625 ENTER();
626
627 if (!pHddCtx)
628 {
629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
630 "%s: HDD context is null", __func__);
631 return -1;
632 }
633
634 if (!pAvoidFreqList)
635 {
636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
637 "%s: pAvoidFreqList is null", __func__);
638 return -1;
639 }
640
641 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
643 NULL,
644#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800645 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530646 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800647 GFP_KERNEL);
648 if (!vendor_event)
649 {
650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
651 "%s: cfg80211_vendor_event_alloc failed", __func__);
652 return -1;
653 }
654
655 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
656 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
657
658 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
659
660 EXIT();
661 return 0;
662}
663#endif /* FEATURE_WLAN_CH_AVOID */
664
Srinivas Dasari030bad32015-02-18 23:23:54 +0530665/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530666 * define short names for the global vendor params
667 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
668 */
669#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
670
671/**
672 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
673 * hang reason
674 * @reason: cds recovery reason
675 *
676 * Return: Vendor specific reason code
677 */
678static enum qca_wlan_vendor_hang_reason
679hdd_convert_hang_reason(enum vos_hang_reason reason)
680{
681 unsigned int ret_val;
682
683 switch (reason) {
684 case VOS_GET_MSG_BUFF_FAILURE:
685 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
686 break;
687 case VOS_ACTIVE_LIST_TIMEOUT:
688 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
689 break;
690 case VOS_SCAN_REQ_EXPIRED:
691 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
692 break;
693 case VOS_TRANSMISSIONS_TIMEOUT:
694 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
695 break;
696 case VOS_DXE_FAILURE:
697 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
698 break;
699 case VOS_WDI_FAILURE:
700 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
701 break;
702 case VOS_REASON_UNSPECIFIED:
703 default:
704 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
705 }
706 return ret_val;
707}
708
709/**
710 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
711 * @hdd_ctx: Pointer to hdd context
712 * @reason: cds recovery reason
713 *
714 * Return: 0 on success or failure reason
715 */
716int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
717 enum vos_hang_reason reason)
718{
719 struct sk_buff *vendor_event;
720 enum qca_wlan_vendor_hang_reason hang_reason;
721
722 ENTER();
723
724 if (!hdd_ctx) {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "HDD context is null");
727 return -EINVAL;
728 }
729
730 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
732 NULL,
733#endif
734 sizeof(unsigned int),
735 HANG_REASON_INDEX,
736 GFP_KERNEL);
737 if (!vendor_event) {
738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
739 "cfg80211_vendor_event_alloc failed");
740 return -ENOMEM;
741 }
742
743 hang_reason = hdd_convert_hang_reason(reason);
744
745 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
746 (unsigned int) hang_reason)) {
747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
748 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
749 kfree_skb(vendor_event);
750 return -EINVAL;
751 }
752
753 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
754
755 EXIT();
756 return 0;
757}
758#undef HANG_REASON_INDEX
759
760/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530761 * FUNCTION: __wlan_hdd_cfg80211_nan_request
762 * This is called when wlan driver needs to send vendor specific
763 * nan request event.
764 */
765static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
766 struct wireless_dev *wdev,
767 const void *data, int data_len)
768{
769 tNanRequestReq nan_req;
770 VOS_STATUS status;
771 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530772 struct net_device *dev = wdev->netdev;
773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
774 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530775 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
776
777 if (0 == data_len)
778 {
779 hddLog(VOS_TRACE_LEVEL_ERROR,
780 FL("NAN - Invalid Request, length = 0"));
781 return ret_val;
782 }
783
784 if (NULL == data)
785 {
786 hddLog(VOS_TRACE_LEVEL_ERROR,
787 FL("NAN - Invalid Request, data is NULL"));
788 return ret_val;
789 }
790
791 status = wlan_hdd_validate_context(pHddCtx);
792 if (0 != status)
793 {
794 hddLog(VOS_TRACE_LEVEL_ERROR,
795 FL("HDD context is not valid"));
796 return -EINVAL;
797 }
798
799 hddLog(LOG1, FL("Received NAN command"));
800 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
801 (tANI_U8 *)data, data_len);
802
803 /* check the NAN Capability */
804 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
805 {
806 hddLog(VOS_TRACE_LEVEL_ERROR,
807 FL("NAN is not supported by Firmware"));
808 return -EINVAL;
809 }
810
811 nan_req.request_data_len = data_len;
812 nan_req.request_data = data;
813
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530814 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530815 if (VOS_STATUS_SUCCESS == status)
816 {
817 ret_val = 0;
818 }
819 return ret_val;
820}
821
822/*
823 * FUNCTION: wlan_hdd_cfg80211_nan_request
824 * Wrapper to protect the nan vendor command from ssr
825 */
826static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
827 struct wireless_dev *wdev,
828 const void *data, int data_len)
829{
830 int ret;
831
832 vos_ssr_protect(__func__);
833 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
834 vos_ssr_unprotect(__func__);
835
836 return ret;
837}
838
839/*
840 * FUNCTION: wlan_hdd_cfg80211_nan_callback
841 * This is a callback function and it gets called
842 * when we need to report nan response event to
843 * upper layers.
844 */
845static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
846{
847 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
848 struct sk_buff *vendor_event;
849 int status;
850 tSirNanEvent *data;
851
852 ENTER();
853 if (NULL == msg)
854 {
855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
856 FL(" msg received here is null"));
857 return;
858 }
859 data = msg;
860
861 status = wlan_hdd_validate_context(pHddCtx);
862
863 if (0 != status)
864 {
865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
866 FL("HDD context is not valid"));
867 return;
868 }
869
870 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
872 NULL,
873#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530874 data->event_data_len +
875 NLMSG_HDRLEN,
876 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
877 GFP_KERNEL);
878
879 if (!vendor_event)
880 {
881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
882 FL("cfg80211_vendor_event_alloc failed"));
883 return;
884 }
885 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
886 data->event_data_len, data->event_data))
887 {
888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
889 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
890 kfree_skb(vendor_event);
891 return;
892 }
893 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
894 EXIT();
895}
896
897/*
898 * FUNCTION: wlan_hdd_cfg80211_nan_init
899 * This function is called to register the callback to sme layer
900 */
901inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
902{
903 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
904}
905
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530906/*
907 * define short names for the global vendor params
908 * used by __wlan_hdd_cfg80211_get_station_cmd()
909 */
910#define STATION_INVALID \
911 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
912#define STATION_INFO \
913 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
914#define STATION_ASSOC_FAIL_REASON \
915 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530916#define STATION_REMOTE \
917 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530918#define STATION_MAX \
919 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
920
921static const struct nla_policy
922hdd_get_station_policy[STATION_MAX + 1] = {
923 [STATION_INFO] = {.type = NLA_FLAG},
924 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
925};
926
927/**
928 * hdd_get_station_assoc_fail() - Handle get station assoc fail
929 * @hdd_ctx: HDD context within host driver
930 * @wdev: wireless device
931 *
932 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
933 * Validate cmd attributes and send the station info to upper layers.
934 *
935 * Return: Success(0) or reason code for failure
936 */
937static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
938 hdd_adapter_t *adapter)
939{
940 struct sk_buff *skb = NULL;
941 uint32_t nl_buf_len;
942 hdd_station_ctx_t *hdd_sta_ctx;
943
944 nl_buf_len = NLMSG_HDRLEN;
945 nl_buf_len += sizeof(uint32_t);
946 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
947
948 if (!skb) {
949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
950 return -ENOMEM;
951 }
952
953 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
954
955 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
956 hdd_sta_ctx->conn_info.assoc_status_code)) {
957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
958 goto fail;
959 }
960 return cfg80211_vendor_cmd_reply(skb);
961fail:
962 if (skb)
963 kfree_skb(skb);
964 return -EINVAL;
965}
966
967/**
968 * hdd_map_auth_type() - transform auth type specific to
969 * vendor command
970 * @auth_type: csr auth type
971 *
972 * Return: Success(0) or reason code for failure
973 */
974static int hdd_convert_auth_type(uint32_t auth_type)
975{
976 uint32_t ret_val;
977
978 switch (auth_type) {
979 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
980 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
981 break;
982 case eCSR_AUTH_TYPE_SHARED_KEY:
983 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
984 break;
985 case eCSR_AUTH_TYPE_WPA:
986 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
987 break;
988 case eCSR_AUTH_TYPE_WPA_PSK:
989 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
990 break;
991 case eCSR_AUTH_TYPE_AUTOSWITCH:
992 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
993 break;
994 case eCSR_AUTH_TYPE_WPA_NONE:
995 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
996 break;
997 case eCSR_AUTH_TYPE_RSN:
998 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
999 break;
1000 case eCSR_AUTH_TYPE_RSN_PSK:
1001 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1002 break;
1003 case eCSR_AUTH_TYPE_FT_RSN:
1004 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1005 break;
1006 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1007 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1008 break;
1009 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1010 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1011 break;
1012 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1013 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1014 break;
1015#ifdef FEATURE_WLAN_ESE
1016 case eCSR_AUTH_TYPE_CCKM_WPA:
1017 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1018 break;
1019 case eCSR_AUTH_TYPE_CCKM_RSN:
1020 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1021 break;
1022#endif
1023 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1024 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1025 break;
1026 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1027 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1028 break;
1029 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1030 case eCSR_AUTH_TYPE_FAILED:
1031 case eCSR_AUTH_TYPE_NONE:
1032 default:
1033 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1034 break;
1035 }
1036 return ret_val;
1037}
1038
1039/**
1040 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1041 * vendor command
1042 * @dot11mode: dot11mode
1043 *
1044 * Return: Success(0) or reason code for failure
1045 */
1046static int hdd_convert_dot11mode(uint32_t dot11mode)
1047{
1048 uint32_t ret_val;
1049
1050 switch (dot11mode) {
1051 case eCSR_CFG_DOT11_MODE_11A:
1052 ret_val = QCA_WLAN_802_11_MODE_11A;
1053 break;
1054 case eCSR_CFG_DOT11_MODE_11B:
1055 ret_val = QCA_WLAN_802_11_MODE_11B;
1056 break;
1057 case eCSR_CFG_DOT11_MODE_11G:
1058 ret_val = QCA_WLAN_802_11_MODE_11G;
1059 break;
1060 case eCSR_CFG_DOT11_MODE_11N:
1061 ret_val = QCA_WLAN_802_11_MODE_11N;
1062 break;
1063 case eCSR_CFG_DOT11_MODE_11AC:
1064 ret_val = QCA_WLAN_802_11_MODE_11AC;
1065 break;
1066 case eCSR_CFG_DOT11_MODE_AUTO:
1067 case eCSR_CFG_DOT11_MODE_ABG:
1068 default:
1069 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1070 }
1071 return ret_val;
1072}
1073
1074/**
1075 * hdd_add_tx_bitrate() - add tx bitrate attribute
1076 * @skb: pointer to sk buff
1077 * @hdd_sta_ctx: pointer to hdd station context
1078 * @idx: attribute index
1079 *
1080 * Return: Success(0) or reason code for failure
1081 */
1082static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1083 hdd_station_ctx_t *hdd_sta_ctx,
1084 int idx)
1085{
1086 struct nlattr *nla_attr;
1087 uint32_t bitrate, bitrate_compat;
1088
1089 nla_attr = nla_nest_start(skb, idx);
1090 if (!nla_attr)
1091 goto fail;
1092 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301093 bitrate = cfg80211_calculate_bitrate(
1094 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301095
1096 /* report 16-bit bitrate only if we can */
1097 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1098 if (bitrate > 0 &&
1099 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1101 goto fail;
1102 }
1103 if (bitrate_compat > 0 &&
1104 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1106 goto fail;
1107 }
1108 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301109 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1111 goto fail;
1112 }
1113 nla_nest_end(skb, nla_attr);
1114 return 0;
1115fail:
1116 return -EINVAL;
1117}
1118
1119/**
1120 * hdd_add_sta_info() - add station info attribute
1121 * @skb: pointer to sk buff
1122 * @hdd_sta_ctx: pointer to hdd station context
1123 * @idx: attribute index
1124 *
1125 * Return: Success(0) or reason code for failure
1126 */
1127static int32_t hdd_add_sta_info(struct sk_buff *skb,
1128 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1129{
1130 struct nlattr *nla_attr;
1131
1132 nla_attr = nla_nest_start(skb, idx);
1133 if (!nla_attr)
1134 goto fail;
1135 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301136 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1138 goto fail;
1139 }
1140 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1141 goto fail;
1142 nla_nest_end(skb, nla_attr);
1143 return 0;
1144fail:
1145 return -EINVAL;
1146}
1147
1148/**
1149 * hdd_add_survey_info() - add survey info attribute
1150 * @skb: pointer to sk buff
1151 * @hdd_sta_ctx: pointer to hdd station context
1152 * @idx: attribute index
1153 *
1154 * Return: Success(0) or reason code for failure
1155 */
1156static int32_t hdd_add_survey_info(struct sk_buff *skb,
1157 hdd_station_ctx_t *hdd_sta_ctx,
1158 int idx)
1159{
1160 struct nlattr *nla_attr;
1161
1162 nla_attr = nla_nest_start(skb, idx);
1163 if (!nla_attr)
1164 goto fail;
1165 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301166 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301167 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301168 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1170 goto fail;
1171 }
1172 nla_nest_end(skb, nla_attr);
1173 return 0;
1174fail:
1175 return -EINVAL;
1176}
1177
1178/**
1179 * hdd_add_link_standard_info() - add link info attribute
1180 * @skb: pointer to sk buff
1181 * @hdd_sta_ctx: pointer to hdd station context
1182 * @idx: attribute index
1183 *
1184 * Return: Success(0) or reason code for failure
1185 */
1186static int32_t
1187hdd_add_link_standard_info(struct sk_buff *skb,
1188 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1189{
1190 struct nlattr *nla_attr;
1191
1192 nla_attr = nla_nest_start(skb, idx);
1193 if (!nla_attr)
1194 goto fail;
1195 if (nla_put(skb,
1196 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301197 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1198 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1200 goto fail;
1201 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301202 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1203 hdd_sta_ctx->cache_conn_info.bssId))
1204 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301205 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1206 goto fail;
1207 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1208 goto fail;
1209 nla_nest_end(skb, nla_attr);
1210 return 0;
1211fail:
1212 return -EINVAL;
1213}
1214
1215/**
1216 * hdd_add_ap_standard_info() - add ap info attribute
1217 * @skb: pointer to sk buff
1218 * @hdd_sta_ctx: pointer to hdd station context
1219 * @idx: attribute index
1220 *
1221 * Return: Success(0) or reason code for failure
1222 */
1223static int32_t
1224hdd_add_ap_standard_info(struct sk_buff *skb,
1225 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1226{
1227 struct nlattr *nla_attr;
1228
1229 nla_attr = nla_nest_start(skb, idx);
1230 if (!nla_attr)
1231 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301232 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301233 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301234 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1235 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1237 goto fail;
1238 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301239 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301240 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301241 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1242 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1244 goto fail;
1245 }
1246 nla_nest_end(skb, nla_attr);
1247 return 0;
1248fail:
1249 return -EINVAL;
1250}
1251
1252/**
1253 * hdd_get_station_info() - send BSS information to supplicant
1254 * @hdd_ctx: pointer to hdd context
1255 * @adapter: pointer to adapter
1256 *
1257 * Return: 0 if success else error status
1258 */
1259static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1260 hdd_adapter_t *adapter)
1261{
1262 struct sk_buff *skb = NULL;
1263 uint8_t *tmp_hs20 = NULL;
1264 uint32_t nl_buf_len;
1265 hdd_station_ctx_t *hdd_sta_ctx;
1266
1267 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1268
1269 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301270
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1272 VOS_MAC_ADDR_SIZE +
1273 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1274 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1275 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301276 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301277 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1279 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1280 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1281 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1284 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1285 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1286 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1287 cache_conn_info.hs20vendor_ie);
1288 nl_buf_len +=
1289 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301290 1);
1291 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301292 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1293 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1294 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1295 nl_buf_len +=
1296 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301297
1298
1299 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1300 if (!skb) {
1301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1302 __func__, __LINE__);
1303 return -ENOMEM;
1304 }
1305
1306 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1307 LINK_INFO_STANDARD_NL80211_ATTR)) {
1308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1309 goto fail;
1310 }
1311 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1312 AP_INFO_STANDARD_NL80211_ATTR)) {
1313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
1316 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301317 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301318 nla_put_u32(skb, INFO_AKM,
1319 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301320 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301321 nla_put_u32(skb, WLAN802_11_MODE,
1322 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1325 goto fail;
1326 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301327 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301329 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1330 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1332 goto fail;
1333 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301334 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301336 (sizeof(hdd_sta_ctx->
1337 cache_conn_info.vht_operation)),
1338 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1340 goto fail;
1341 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301342 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301343 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301344 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1345 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1347 goto fail;
1348 }
1349
1350 return cfg80211_vendor_cmd_reply(skb);
1351fail:
1352 if (skb)
1353 kfree_skb(skb);
1354 return -EINVAL;
1355}
1356
1357/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301358 * hdd_add_survey_info_sap_get_len - get data length used in
1359 * hdd_add_survey_info_sap()
1360 *
1361 * This function calculates the data length used in hdd_add_survey_info_sap()
1362 *
1363 * Return: total data length used in hdd_add_survey_info_sap()
1364 */
1365static uint32_t hdd_add_survey_info_sap_get_len(void)
1366{
1367 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1368}
1369
1370/**
1371 * hdd_add_survey_info - add survey info attribute
1372 * @skb: pointer to response skb buffer
1373 * @stainfo: station information
1374 * @idx: attribute type index for nla_next_start()
1375 *
1376 * This function adds survey info attribute to response skb buffer
1377 *
1378 * Return : 0 on success and errno on failure
1379 */
1380static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1381 struct hdd_cache_sta_info *stainfo,
1382 int idx)
1383{
1384 struct nlattr *nla_attr;
1385
1386 nla_attr = nla_nest_start(skb, idx);
1387 if (!nla_attr)
1388 goto fail;
1389 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1390 stainfo->freq)) {
1391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1392 FL("put fail"));
1393 goto fail;
1394 }
1395 nla_nest_end(skb, nla_attr);
1396 return 0;
1397fail:
1398 return -EINVAL;
1399}
1400
1401/**
1402 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1403 * hdd_add_tx_bitrate_sap()
1404 *
1405 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1406 *
1407 * Return: total data length used in hdd_add_tx_bitrate_sap()
1408 */
1409static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1410{
1411 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1412}
1413
1414/**
1415 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1416 * @skb: pointer to response skb buffer
1417 * @stainfo: station information
1418 * @idx: attribute type index for nla_next_start()
1419 *
1420 * This function adds vht nss attribute to response skb buffer
1421 *
1422 * Return : 0 on success and errno on failure
1423 */
1424static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1425 struct hdd_cache_sta_info *stainfo,
1426 int idx)
1427{
1428 struct nlattr *nla_attr;
1429
1430 nla_attr = nla_nest_start(skb, idx);
1431 if (!nla_attr)
1432 goto fail;
1433
1434 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1435 stainfo->nss)) {
1436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1437 FL("put fail"));
1438 goto fail;
1439 }
1440 nla_nest_end(skb, nla_attr);
1441 return 0;
1442fail:
1443 return -EINVAL;
1444}
1445
1446/**
1447 * hdd_add_sta_info_sap_get_len - get data length used in
1448 * hdd_add_sta_info_sap()
1449 *
1450 * This function calculates the data length used in hdd_add_sta_info_sap()
1451 *
1452 * Return: total data length used in hdd_add_sta_info_sap()
1453 */
1454static uint32_t hdd_add_sta_info_sap_get_len(void)
1455{
1456 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1457 hdd_add_tx_bitrate_sap_get_len());
1458}
1459
1460/**
1461 * hdd_add_sta_info_sap - add sta signal info attribute
1462 * @skb: pointer to response skb buffer
1463 * @rssi: peer rssi value
1464 * @stainfo: station information
1465 * @idx: attribute type index for nla_next_start()
1466 *
1467 * This function adds sta signal attribute to response skb buffer
1468 *
1469 * Return : 0 on success and errno on failure
1470 */
1471static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1472 struct hdd_cache_sta_info *stainfo, int idx)
1473{
1474 struct nlattr *nla_attr;
1475
1476 nla_attr = nla_nest_start(skb, idx);
1477 if (!nla_attr)
1478 goto fail;
1479
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301480 /* upperlayer expects positive rssi value */
1481 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1483 FL("put fail"));
1484 goto fail;
1485 }
1486 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1488 FL("put fail"));
1489 goto fail;
1490 }
1491
1492 nla_nest_end(skb, nla_attr);
1493 return 0;
1494fail:
1495 return -EINVAL;
1496}
1497
1498/**
1499 * hdd_add_link_standard_info_sap_get_len - get data length used in
1500 * hdd_add_link_standard_info_sap()
1501 *
1502 * This function calculates the data length used in
1503 * hdd_add_link_standard_info_sap()
1504 *
1505 * Return: total data length used in hdd_add_link_standard_info_sap()
1506 */
1507static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1508{
1509 return ((NLA_HDRLEN) +
1510 hdd_add_survey_info_sap_get_len() +
1511 hdd_add_sta_info_sap_get_len() +
1512 (sizeof(uint32_t) + NLA_HDRLEN));
1513}
1514
1515/**
1516 * hdd_add_link_standard_info_sap - add add link info attribut
1517 * @skb: pointer to response skb buffer
1518 * @stainfo: station information
1519 * @idx: attribute type index for nla_next_start()
1520 *
1521 * This function adds link info attribut to response skb buffer
1522 *
1523 * Return : 0 on success and errno on failure
1524 */
1525static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1526 struct hdd_cache_sta_info *stainfo,
1527 int idx)
1528{
1529 struct nlattr *nla_attr;
1530
1531 nla_attr = nla_nest_start(skb, idx);
1532 if (!nla_attr)
1533 goto fail;
1534 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1535 goto fail;
1536 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1537 goto fail;
1538
1539 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1541 FL("put fail"));
1542 goto fail;
1543 }
1544
1545 nla_nest_end(skb, nla_attr);
1546 return 0;
1547fail:
1548 return -EINVAL;
1549}
1550
1551/**
1552 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1553 * hdd_add_ap_standard_info_sap()
1554 * @stainfo: station information
1555 *
1556 * This function calculates the data length used in
1557 * hdd_add_ap_standard_info_sap()
1558 *
1559 * Return: total data length used in hdd_add_ap_standard_info_sap()
1560 */
1561static uint32_t hdd_add_ap_standard_info_sap_get_len(
1562 struct hdd_cache_sta_info *stainfo)
1563{
1564 uint32_t len;
1565
1566 len = NLA_HDRLEN;
1567 if (stainfo->vht_present)
1568 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1569 if (stainfo->ht_present)
1570 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1571
1572 return len;
1573}
1574
1575/**
1576 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1577 * @skb: pointer to response skb buffer
1578 * @stainfo: station information
1579 * @idx: attribute type index for nla_next_start()
1580 *
1581 * This function adds HT and VHT info attributes to response skb buffer
1582 *
1583 * Return : 0 on success and errno on failure
1584 */
1585static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1586 struct hdd_cache_sta_info *stainfo,
1587 int idx)
1588{
1589 struct nlattr *nla_attr;
1590
1591 nla_attr = nla_nest_start(skb, idx);
1592 if (!nla_attr)
1593 goto fail;
1594
1595 if (stainfo->vht_present) {
1596 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1597 sizeof(stainfo->vht_caps),
1598 &stainfo->vht_caps)) {
1599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1600 FL("put fail"));
1601 goto fail;
1602 }
1603 }
1604 if (stainfo->ht_present) {
1605 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1606 sizeof(stainfo->ht_caps),
1607 &stainfo->ht_caps)) {
1608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1609 FL("put fail"));
1610 goto fail;
1611 }
1612 }
1613 nla_nest_end(skb, nla_attr);
1614 return 0;
1615fail:
1616 return -EINVAL;
1617}
1618
1619/**
1620 * hdd_decode_ch_width - decode channel band width based
1621 * @ch_width: encoded enum value holding channel band width
1622 *
1623 * This function decodes channel band width from the given encoded enum value.
1624 *
1625 * Returns: decoded channel band width.
1626 */
1627static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1628{
1629 switch (ch_width) {
1630 case 0:
1631 return 20;
1632 case 1:
1633 return 40;
1634 case 2:
1635 return 80;
1636 default:
1637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1638 "invalid enum: %d", ch_width);
1639 return 20;
1640 }
1641}
1642
1643/**
1644 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1645 * @hdd_ctx: hdd context
1646 * @adapter: hostapd interface
1647 * @mac_addr: mac address of requested peer
1648 *
1649 * This function collect and indicate the cached(deleted) peer's info
1650 *
1651 * Return: 0 on success, otherwise error value
1652 */
1653static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1654 hdd_adapter_t *adapter,
1655 v_MACADDR_t mac_addr)
1656{
1657 struct hdd_cache_sta_info *stainfo;
1658 struct sk_buff *skb = NULL;
1659 uint32_t nl_buf_len;
1660 uint8_t cw;
1661 ptSapContext sap_ctx;
1662 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1663
1664 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1665 if(sap_ctx == NULL){
1666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1667 FL("psapCtx is NULL"));
1668 return -ENOENT;
1669 }
1670
1671 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1672 mac_addr.bytes);
1673 if (!stainfo) {
1674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1675 "peer " MAC_ADDRESS_STR " not found",
1676 MAC_ADDR_ARRAY(mac_addr.bytes));
1677 return -EINVAL;
1678 }
1679 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1681 "peer " MAC_ADDRESS_STR " is in connected state",
1682 MAC_ADDR_ARRAY(mac_addr.bytes));
1683 return -EINVAL;
1684 }
1685
1686
1687 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1688 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1689 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1690 (sizeof(cw) + NLA_HDRLEN) +
1691 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1692
1693 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1694 if (!skb) {
1695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1696 return -ENOMEM;
1697 }
1698
1699 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1700 LINK_INFO_STANDARD_NL80211_ATTR)) {
1701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1702 goto fail;
1703 }
1704
1705 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1706 AP_INFO_STANDARD_NL80211_ATTR)) {
1707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1708 goto fail;
1709 }
1710
1711 /* upper layer expects decoded channel BW */
1712 cw = hdd_decode_ch_width(stainfo->ch_width);
1713 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1714 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1716 goto fail;
1717 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301718 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1720 goto fail;
1721 }
1722
1723 vos_mem_zero(stainfo, sizeof(*stainfo));
1724
1725 return cfg80211_vendor_cmd_reply(skb);
1726fail:
1727 if (skb)
1728 kfree_skb(skb);
1729
1730 return -EINVAL;
1731}
1732
1733/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301734 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1735 * @wiphy: corestack handler
1736 * @wdev: wireless device
1737 * @data: data
1738 * @data_len: data length
1739 *
1740 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1741 * Validate cmd attributes and send the station info to upper layers.
1742 *
1743 * Return: Success(0) or reason code for failure
1744 */
1745static int32_t
1746__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1747 struct wireless_dev *wdev,
1748 const void *data,
1749 int data_len)
1750{
1751 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1752 struct net_device *dev = wdev->netdev;
1753 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1754 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1755 int32_t status;
1756
1757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1758 if (VOS_FTM_MODE == hdd_get_conparam()) {
1759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1760 status = -EPERM;
1761 goto out;
1762 }
1763
1764 status = wlan_hdd_validate_context(hdd_ctx);
1765 if (0 != status)
1766 goto out;
1767
1768
1769 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1770 data, data_len, NULL);
1771 if (status) {
1772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1773 goto out;
1774 }
1775
1776 /* Parse and fetch Command Type*/
1777 if (tb[STATION_INFO]) {
1778 status = hdd_get_station_info(hdd_ctx, adapter);
1779 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1780 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301781 } else if (tb[STATION_REMOTE]) {
1782 v_MACADDR_t mac_addr;
1783
1784 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1785 adapter->device_mode != WLAN_HDD_P2P_GO) {
1786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1787 adapter->device_mode);
1788 status = -EINVAL;
1789 goto out;
1790 }
1791
1792 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1793 VOS_MAC_ADDRESS_LEN);
1794
1795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1796 MAC_ADDR_ARRAY(mac_addr.bytes));
1797
1798 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1799 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301800 } else {
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1802 status = -EINVAL;
1803 goto out;
1804 }
1805 EXIT();
1806out:
1807 return status;
1808}
1809
1810/**
1811 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1812 * @wiphy: corestack handler
1813 * @wdev: wireless device
1814 * @data: data
1815 * @data_len: data length
1816 *
1817 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1818 * Validate cmd attributes and send the station info to upper layers.
1819 *
1820 * Return: Success(0) or reason code for failure
1821 */
1822static int32_t
1823hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1824 struct wireless_dev *wdev,
1825 const void *data,
1826 int data_len)
1827{
1828 int ret;
1829
1830 vos_ssr_protect(__func__);
1831 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1832 vos_ssr_unprotect(__func__);
1833
1834 return ret;
1835}
1836
1837/*
1838 * undef short names defined for get station command
1839 * used by __wlan_hdd_cfg80211_get_station_cmd()
1840 */
1841#undef STATION_INVALID
1842#undef STATION_INFO
1843#undef STATION_ASSOC_FAIL_REASON
1844#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301845
Sunil Duttc69bccb2014-05-26 21:30:20 +05301846#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1847
1848static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1849 struct sk_buff *vendor_event)
1850{
1851 if (nla_put_u8(vendor_event,
1852 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1853 stats->rate.preamble) ||
1854 nla_put_u8(vendor_event,
1855 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1856 stats->rate.nss) ||
1857 nla_put_u8(vendor_event,
1858 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1859 stats->rate.bw) ||
1860 nla_put_u8(vendor_event,
1861 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1862 stats->rate.rateMcsIdx) ||
1863 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1864 stats->rate.bitrate ) ||
1865 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1866 stats->txMpdu ) ||
1867 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1868 stats->rxMpdu ) ||
1869 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1870 stats->mpduLost ) ||
1871 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1872 stats->retries) ||
1873 nla_put_u32(vendor_event,
1874 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1875 stats->retriesShort ) ||
1876 nla_put_u32(vendor_event,
1877 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1878 stats->retriesLong))
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR,
1881 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1882 return FALSE;
1883 }
1884 return TRUE;
1885}
1886
1887static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1888 struct sk_buff *vendor_event)
1889{
1890 u32 i = 0;
1891 struct nlattr *rateInfo;
1892 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1893 stats->type) ||
1894 nla_put(vendor_event,
1895 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1896 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1897 nla_put_u32(vendor_event,
1898 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1899 stats->capabilities) ||
1900 nla_put_u32(vendor_event,
1901 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1902 stats->numRate))
1903 {
1904 hddLog(VOS_TRACE_LEVEL_ERROR,
1905 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1906 goto error;
1907 }
1908
1909 rateInfo = nla_nest_start(vendor_event,
1910 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301911 if(!rateInfo)
1912 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301913 for (i = 0; i < stats->numRate; i++)
1914 {
1915 struct nlattr *rates;
1916 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1917 stats->rateStats +
1918 (i * sizeof(tSirWifiRateStat)));
1919 rates = nla_nest_start(vendor_event, i);
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05301920
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301921 if(!rates)
1922 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1925 {
1926 hddLog(VOS_TRACE_LEVEL_ERROR,
1927 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1928 return FALSE;
1929 }
1930 nla_nest_end(vendor_event, rates);
1931 }
1932 nla_nest_end(vendor_event, rateInfo);
1933
1934 return TRUE;
1935error:
1936 return FALSE;
1937}
1938
1939static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1940 struct sk_buff *vendor_event)
1941{
1942 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1943 stats->ac ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1946 stats->txMpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1949 stats->rxMpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1952 stats->txMcast ) ||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1955 stats->rxMcast ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1958 stats->rxAmpdu ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1961 stats->txAmpdu ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1964 stats->mpduLost )||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1967 stats->retries ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1970 stats->retriesShort ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1973 stats->retriesLong ) ||
1974 nla_put_u32(vendor_event,
1975 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1976 stats->contentionTimeMin ) ||
1977 nla_put_u32(vendor_event,
1978 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1979 stats->contentionTimeMax ) ||
1980 nla_put_u32(vendor_event,
1981 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1982 stats->contentionTimeAvg ) ||
1983 nla_put_u32(vendor_event,
1984 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1985 stats->contentionNumSamples ))
1986 {
1987 hddLog(VOS_TRACE_LEVEL_ERROR,
1988 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1989 return FALSE;
1990 }
1991 return TRUE;
1992}
1993
1994static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1995 struct sk_buff *vendor_event)
1996{
Dino Myclec8f3f332014-07-21 16:48:27 +05301997 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301998 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
2001 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2002 nla_put_u32(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2004 stats->state ) ||
2005 nla_put_u32(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2007 stats->roaming ) ||
2008 nla_put_u32(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2010 stats->capabilities ) ||
2011 nla_put(vendor_event,
2012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2013 strlen(stats->ssid), stats->ssid) ||
2014 nla_put(vendor_event,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2016 WNI_CFG_BSSID_LEN, stats->bssid) ||
2017 nla_put(vendor_event,
2018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2019 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2020 nla_put(vendor_event,
2021 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2022 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2023 )
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR,
2026 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2027 return FALSE;
2028 }
2029 return TRUE;
2030}
2031
Dino Mycle3b9536d2014-07-09 22:05:24 +05302032static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2033 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302034 struct sk_buff *vendor_event)
2035{
2036 int i = 0;
2037 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302038 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2039 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302040 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302041
Sunil Duttc69bccb2014-05-26 21:30:20 +05302042 if (FALSE == put_wifi_interface_info(
2043 &pWifiIfaceStat->info,
2044 vendor_event))
2045 {
2046 hddLog(VOS_TRACE_LEVEL_ERROR,
2047 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2048 return FALSE;
2049
2050 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302051 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2052 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2053 if (NULL == pWifiIfaceStatTL)
2054 {
2055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2056 return FALSE;
2057 }
2058
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302059 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2060 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2061 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2062 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2063
2064 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2065 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302068
2069 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2070 {
2071 if (VOS_STATUS_SUCCESS ==
2072 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2073 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2074 {
2075 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2076 * obtained from TL structure
2077 */
2078
2079 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2080 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302081 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2082
Srinivas Dasari98947432014-11-07 19:41:24 +05302083 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2084 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2085 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2086 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2087 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2088 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2089 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302091
Srinivas Dasari98947432014-11-07 19:41:24 +05302092 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2093 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2094 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2095 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2096 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2097 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2098 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2099 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302100
Srinivas Dasari98947432014-11-07 19:41:24 +05302101 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2102 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2104 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2106 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2108 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302109 }
2110 else
2111 {
2112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2113 }
2114
Dino Mycle3b9536d2014-07-09 22:05:24 +05302115 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2116 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2117 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2118 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2119 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2120 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2121 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2122 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2123 }
2124 else
2125 {
2126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2127 }
2128
2129
Sunil Duttc69bccb2014-05-26 21:30:20 +05302130
2131 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302132 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2133 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2134 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2136 pWifiIfaceStat->beaconRx) ||
2137 nla_put_u32(vendor_event,
2138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2139 pWifiIfaceStat->mgmtRx) ||
2140 nla_put_u32(vendor_event,
2141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2142 pWifiIfaceStat->mgmtActionRx) ||
2143 nla_put_u32(vendor_event,
2144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2145 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302146 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2148 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302149 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2151 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302152 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302153 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2154 pWifiIfaceStat->rssiAck))
2155 {
2156 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302157 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2158 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302159 return FALSE;
2160 }
2161
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302162#ifdef FEATURE_EXT_LL_STAT
2163 /*
2164 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2165 * then host should send Leaky AP stats to upper layer,
2166 * otherwise no need to send these stats.
2167 */
2168 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2169 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2170 )
2171 {
2172 hddLog(VOS_TRACE_LEVEL_INFO,
2173 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2174 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2175 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2176 pWifiIfaceStat->leakyApStat.rx_leak_window,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2178 if (nla_put_u32(vendor_event,
2179 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2180 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2181 nla_put_u32(vendor_event,
2182 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2183 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2184 nla_put_u32(vendor_event,
2185 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2186 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302187 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302188 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2189 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2190 {
2191 hddLog(VOS_TRACE_LEVEL_ERROR,
2192 FL("EXT_LL_STAT put fail"));
2193 vos_mem_free(pWifiIfaceStatTL);
2194 return FALSE;
2195 }
2196 }
2197#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302198 wmmInfo = nla_nest_start(vendor_event,
2199 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302200 if(!wmmInfo)
2201 {
2202 vos_mem_free(pWifiIfaceStatTL);
2203 return FALSE;
2204 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302205 for (i = 0; i < WIFI_AC_MAX; i++)
2206 {
2207 struct nlattr *wmmStats;
2208 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302209 if(!wmmStats)
2210 {
2211 vos_mem_free(pWifiIfaceStatTL);
2212 return FALSE;
2213 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 if (FALSE == put_wifi_wmm_ac_stat(
2215 &pWifiIfaceStat->AccessclassStats[i],
2216 vendor_event))
2217 {
2218 hddLog(VOS_TRACE_LEVEL_ERROR,
2219 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302220 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302221 return FALSE;
2222 }
2223
2224 nla_nest_end(vendor_event, wmmStats);
2225 }
2226 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302227 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302228 return TRUE;
2229}
2230
2231static tSirWifiInterfaceMode
2232 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2233{
2234 switch (deviceMode)
2235 {
2236 case WLAN_HDD_INFRA_STATION:
2237 return WIFI_INTERFACE_STA;
2238 case WLAN_HDD_SOFTAP:
2239 return WIFI_INTERFACE_SOFTAP;
2240 case WLAN_HDD_P2P_CLIENT:
2241 return WIFI_INTERFACE_P2P_CLIENT;
2242 case WLAN_HDD_P2P_GO:
2243 return WIFI_INTERFACE_P2P_GO;
2244 case WLAN_HDD_IBSS:
2245 return WIFI_INTERFACE_IBSS;
2246 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302247 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302248 }
2249}
2250
2251static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2252 tpSirWifiInterfaceInfo pInfo)
2253{
2254 v_U8_t *staMac = NULL;
2255 hdd_station_ctx_t *pHddStaCtx;
2256 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2257 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2258
2259 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2260
2261 vos_mem_copy(pInfo->macAddr,
2262 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2263
2264 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2265 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2266 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2267 {
2268 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2269 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2270 {
2271 pInfo->state = WIFI_DISCONNECTED;
2272 }
2273 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2274 {
2275 hddLog(VOS_TRACE_LEVEL_ERROR,
2276 "%s: Session ID %d, Connection is in progress", __func__,
2277 pAdapter->sessionId);
2278 pInfo->state = WIFI_ASSOCIATING;
2279 }
2280 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2281 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2282 {
2283 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2284 hddLog(VOS_TRACE_LEVEL_ERROR,
2285 "%s: client " MAC_ADDRESS_STR
2286 " is in the middle of WPS/EAPOL exchange.", __func__,
2287 MAC_ADDR_ARRAY(staMac));
2288 pInfo->state = WIFI_AUTHENTICATING;
2289 }
2290 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2291 {
2292 pInfo->state = WIFI_ASSOCIATED;
2293 vos_mem_copy(pInfo->bssid,
2294 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2295 vos_mem_copy(pInfo->ssid,
2296 pHddStaCtx->conn_info.SSID.SSID.ssId,
2297 pHddStaCtx->conn_info.SSID.SSID.length);
2298 //NULL Terminate the string.
2299 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2300 }
2301 }
2302 vos_mem_copy(pInfo->countryStr,
2303 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2304
2305 vos_mem_copy(pInfo->apCountryStr,
2306 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2307
2308 return TRUE;
2309}
2310
2311/*
2312 * hdd_link_layer_process_peer_stats () - This function is called after
2313 * receiving Link Layer Peer statistics from FW.This function converts
2314 * the firmware data to the NL data and sends the same to the kernel/upper
2315 * layers.
2316 */
2317static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2318 v_VOID_t *pData)
2319{
2320 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 tpSirWifiPeerStat pWifiPeerStat;
2322 tpSirWifiPeerInfo pWifiPeerInfo;
2323 struct nlattr *peerInfo;
2324 struct sk_buff *vendor_event;
2325 int status, i;
2326
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302327 ENTER();
2328
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 status = wlan_hdd_validate_context(pHddCtx);
2330 if (0 != status)
2331 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302332 return;
2333 }
2334
2335 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2336
2337 hddLog(VOS_TRACE_LEVEL_INFO,
2338 "LL_STATS_PEER_ALL : numPeers %u",
2339 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302340 /*
2341 * Allocate a size of 4096 for the peer stats comprising
2342 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2343 * sizeof (tSirWifiRateStat).Each field is put with an
2344 * NL attribute.The size of 4096 is considered assuming
2345 * that number of rates shall not exceed beyond 50 with
2346 * the sizeof (tSirWifiRateStat) being 32.
2347 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302348 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2349 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302350 if (!vendor_event)
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302353 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302354 __func__);
2355 return;
2356 }
2357 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302358 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2360 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302361 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2362 pWifiPeerStat->numPeers))
2363 {
2364 hddLog(VOS_TRACE_LEVEL_ERROR,
2365 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2366 kfree_skb(vendor_event);
2367 return;
2368 }
2369
2370 peerInfo = nla_nest_start(vendor_event,
2371 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302372 if(!peerInfo)
2373 {
2374 hddLog(VOS_TRACE_LEVEL_ERROR,
2375 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2376 __func__);
2377 kfree_skb(vendor_event);
2378 return;
2379 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302380
2381 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2382 pWifiPeerStat->peerInfo);
2383
2384 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2385 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302386 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302387 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302388
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302389 if(!peers)
2390 {
2391 hddLog(VOS_TRACE_LEVEL_ERROR,
2392 "%s: peer stats put fail",
2393 __func__);
2394 kfree_skb(vendor_event);
2395 return;
2396 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302397 if (FALSE == put_wifi_peer_info(
2398 pWifiPeerInfo, vendor_event))
2399 {
2400 hddLog(VOS_TRACE_LEVEL_ERROR,
2401 "%s: put_wifi_peer_info put fail", __func__);
2402 kfree_skb(vendor_event);
2403 return;
2404 }
2405
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05302406 pWifiPeerInfo = (tpSirWifiPeerInfo)((uint8 *)pWifiPeerInfo +
2407 (sizeof(tSirWifiPeerInfo) - sizeof(tSirWifiRateStat)) +
2408 (numRate * sizeof(tSirWifiRateStat)));
2409
Sunil Duttc69bccb2014-05-26 21:30:20 +05302410 nla_nest_end(vendor_event, peers);
2411 }
2412 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302413 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302415}
2416
2417/*
2418 * hdd_link_layer_process_iface_stats () - This function is called after
2419 * receiving Link Layer Interface statistics from FW.This function converts
2420 * the firmware data to the NL data and sends the same to the kernel/upper
2421 * layers.
2422 */
2423static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2424 v_VOID_t *pData)
2425{
2426 tpSirWifiIfaceStat pWifiIfaceStat;
2427 struct sk_buff *vendor_event;
2428 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2429 int status;
2430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302431 ENTER();
2432
Sunil Duttc69bccb2014-05-26 21:30:20 +05302433 status = wlan_hdd_validate_context(pHddCtx);
2434 if (0 != status)
2435 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302436 return;
2437 }
2438 /*
2439 * Allocate a size of 4096 for the interface stats comprising
2440 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2441 * assuming that all these fit with in the limit.Please take
2442 * a call on the limit based on the data requirements on
2443 * interface statistics.
2444 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302447 if (!vendor_event)
2448 {
2449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302451 return;
2452 }
2453
2454 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2455
Dino Mycle3b9536d2014-07-09 22:05:24 +05302456
2457 if (FALSE == hdd_get_interface_info( pAdapter,
2458 &pWifiIfaceStat->info))
2459 {
2460 hddLog(VOS_TRACE_LEVEL_ERROR,
2461 FL("hdd_get_interface_info get fail") );
2462 kfree_skb(vendor_event);
2463 return;
2464 }
2465
2466 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2467 vendor_event))
2468 {
2469 hddLog(VOS_TRACE_LEVEL_ERROR,
2470 FL("put_wifi_iface_stats fail") );
2471 kfree_skb(vendor_event);
2472 return;
2473 }
2474
Sunil Duttc69bccb2014-05-26 21:30:20 +05302475 hddLog(VOS_TRACE_LEVEL_INFO,
2476 "WMI_LINK_STATS_IFACE Data");
2477
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302478 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302479
2480 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302481}
2482
2483/*
2484 * hdd_link_layer_process_radio_stats () - This function is called after
2485 * receiving Link Layer Radio statistics from FW.This function converts
2486 * the firmware data to the NL data and sends the same to the kernel/upper
2487 * layers.
2488 */
2489static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2490 v_VOID_t *pData)
2491{
2492 int status, i;
2493 tpSirWifiRadioStat pWifiRadioStat;
2494 tpSirWifiChannelStats pWifiChannelStats;
2495 struct sk_buff *vendor_event;
2496 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2497 struct nlattr *chList;
2498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302499 ENTER();
2500
Sunil Duttc69bccb2014-05-26 21:30:20 +05302501 status = wlan_hdd_validate_context(pHddCtx);
2502 if (0 != status)
2503 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302504 return;
2505 }
2506 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2507
2508 hddLog(VOS_TRACE_LEVEL_INFO,
2509 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302510 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302511 " radio is %d onTime is %u "
2512 " txTime is %u rxTime is %u "
2513 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302514 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515 " onTimePnoScan is %u onTimeHs20 is %u "
2516 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302517 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302518 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2519 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2520 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302521 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302522 pWifiRadioStat->onTimeRoamScan,
2523 pWifiRadioStat->onTimePnoScan,
2524 pWifiRadioStat->onTimeHs20,
2525 pWifiRadioStat->numChannels);
2526 /*
2527 * Allocate a size of 4096 for the Radio stats comprising
2528 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2529 * (tSirWifiChannelStats).Each channel data is put with an
2530 * NL attribute.The size of 4096 is considered assuming that
2531 * number of channels shall not exceed beyond 60 with the
2532 * sizeof (tSirWifiChannelStats) being 24 bytes.
2533 */
2534
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302535 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2536 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302537 if (!vendor_event)
2538 {
2539 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302540 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302541 return;
2542 }
2543
2544 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302545 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2546 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2547 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2549 pWifiRadioStat->radio) ||
2550 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302551 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2552 NUM_RADIOS) ||
2553 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2555 pWifiRadioStat->onTime) ||
2556 nla_put_u32(vendor_event,
2557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2558 pWifiRadioStat->txTime) ||
2559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2561 pWifiRadioStat->rxTime) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2564 pWifiRadioStat->onTimeScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2567 pWifiRadioStat->onTimeNbd) ||
2568 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2570 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302571 nla_put_u32(vendor_event,
2572 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2573 pWifiRadioStat->onTimeRoamScan) ||
2574 nla_put_u32(vendor_event,
2575 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2576 pWifiRadioStat->onTimePnoScan) ||
2577 nla_put_u32(vendor_event,
2578 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2579 pWifiRadioStat->onTimeHs20) ||
2580 nla_put_u32(vendor_event,
2581 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2582 pWifiRadioStat->numChannels))
2583 {
2584 hddLog(VOS_TRACE_LEVEL_ERROR,
2585 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2586 kfree_skb(vendor_event);
2587 return ;
2588 }
2589
2590 chList = nla_nest_start(vendor_event,
2591 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302592 if(!chList)
2593 {
2594 hddLog(VOS_TRACE_LEVEL_ERROR,
2595 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2596 __func__);
2597 kfree_skb(vendor_event);
2598 return;
2599 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302600 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2601 {
2602 struct nlattr *chInfo;
2603
2604 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2605 pWifiRadioStat->channels +
2606 (i * sizeof(tSirWifiChannelStats)));
2607
Sunil Duttc69bccb2014-05-26 21:30:20 +05302608 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302609 if(!chInfo)
2610 {
2611 hddLog(VOS_TRACE_LEVEL_ERROR,
2612 "%s: failed to put chInfo",
2613 __func__);
2614 kfree_skb(vendor_event);
2615 return;
2616 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302617
2618 if (nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2620 pWifiChannelStats->channel.width) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2623 pWifiChannelStats->channel.centerFreq) ||
2624 nla_put_u32(vendor_event,
2625 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2626 pWifiChannelStats->channel.centerFreq0) ||
2627 nla_put_u32(vendor_event,
2628 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2629 pWifiChannelStats->channel.centerFreq1) ||
2630 nla_put_u32(vendor_event,
2631 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2632 pWifiChannelStats->onTime) ||
2633 nla_put_u32(vendor_event,
2634 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2635 pWifiChannelStats->ccaBusyTime))
2636 {
2637 hddLog(VOS_TRACE_LEVEL_ERROR,
2638 FL("cfg80211_vendor_event_alloc failed") );
2639 kfree_skb(vendor_event);
2640 return ;
2641 }
2642 nla_nest_end(vendor_event, chInfo);
2643 }
2644 nla_nest_end(vendor_event, chList);
2645
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302646 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302647
2648 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302649 return;
2650}
2651
2652/*
2653 * hdd_link_layer_stats_ind_callback () - This function is called after
2654 * receiving Link Layer indications from FW.This callback converts the firmware
2655 * data to the NL data and send the same to the kernel/upper layers.
2656 */
2657static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2658 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302659 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660{
Dino Mycled3d50022014-07-07 12:58:25 +05302661 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2662 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302663 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302664 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665 int status;
2666
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302667 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302668
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302669 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302670 if (0 != status)
2671 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 return;
2673 }
2674
Dino Mycled3d50022014-07-07 12:58:25 +05302675 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2676 if (NULL == pAdapter)
2677 {
2678 hddLog(VOS_TRACE_LEVEL_ERROR,
2679 FL(" MAC address %pM does not exist with host"),
2680 macAddr);
2681 return;
2682 }
2683
Sunil Duttc69bccb2014-05-26 21:30:20 +05302684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302685 "%s: Interface: %s LLStats indType: %d", __func__,
2686 pAdapter->dev->name, indType);
2687
Sunil Duttc69bccb2014-05-26 21:30:20 +05302688 switch (indType)
2689 {
2690 case SIR_HAL_LL_STATS_RESULTS_RSP:
2691 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302692 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302693 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2694 "respId = %u, moreResultToFollow = %u",
2695 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2696 macAddr, linkLayerStatsResults->respId,
2697 linkLayerStatsResults->moreResultToFollow);
2698
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302699 spin_lock(&hdd_context_lock);
2700 context = &pHddCtx->ll_stats_context;
2701 /* validate response received from target */
2702 if ((context->request_id != linkLayerStatsResults->respId) ||
2703 !(context->request_bitmap & linkLayerStatsResults->paramId))
2704 {
2705 spin_unlock(&hdd_context_lock);
2706 hddLog(LOGE,
2707 FL("Error : Request id %d response id %d request bitmap 0x%x"
2708 "response bitmap 0x%x"),
2709 context->request_id, linkLayerStatsResults->respId,
2710 context->request_bitmap, linkLayerStatsResults->paramId);
2711 return;
2712 }
2713 spin_unlock(&hdd_context_lock);
2714
Sunil Duttc69bccb2014-05-26 21:30:20 +05302715 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2716 {
2717 hdd_link_layer_process_radio_stats(pAdapter,
2718 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302719 spin_lock(&hdd_context_lock);
2720 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2721 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302722 }
2723 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2724 {
2725 hdd_link_layer_process_iface_stats(pAdapter,
2726 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302727 spin_lock(&hdd_context_lock);
2728 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2729 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302730 }
2731 else if ( linkLayerStatsResults->paramId &
2732 WMI_LINK_STATS_ALL_PEER )
2733 {
2734 hdd_link_layer_process_peer_stats(pAdapter,
2735 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302736 spin_lock(&hdd_context_lock);
2737 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2738 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302739 } /* WMI_LINK_STATS_ALL_PEER */
2740 else
2741 {
2742 hddLog(VOS_TRACE_LEVEL_ERROR,
2743 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2744 }
2745
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302746 spin_lock(&hdd_context_lock);
2747 /* complete response event if all requests are completed */
2748 if (0 == context->request_bitmap)
2749 complete(&context->response_event);
2750 spin_unlock(&hdd_context_lock);
2751
Sunil Duttc69bccb2014-05-26 21:30:20 +05302752 break;
2753 }
2754 default:
2755 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2756 break;
2757 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302758
2759 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302760 return;
2761}
2762
2763const struct
2764nla_policy
2765qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2766{
2767 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2768 { .type = NLA_U32 },
2769 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2770 { .type = NLA_U32 },
2771};
2772
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302773static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2774 struct wireless_dev *wdev,
2775 const void *data,
2776 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302777{
2778 int status;
2779 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302780 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302781 struct net_device *dev = wdev->netdev;
2782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302785 ENTER();
2786
Sunil Duttc69bccb2014-05-26 21:30:20 +05302787 status = wlan_hdd_validate_context(pHddCtx);
2788 if (0 != status)
2789 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302790 return -EINVAL;
2791 }
2792
2793 if (NULL == pAdapter)
2794 {
2795 hddLog(VOS_TRACE_LEVEL_ERROR,
2796 FL("HDD adapter is Null"));
2797 return -ENODEV;
2798 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302799 /* check the LLStats Capability */
2800 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2801 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2802 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302803 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302804 FL("Link Layer Statistics not supported by Firmware"));
2805 return -EINVAL;
2806 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302807
2808 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2809 (struct nlattr *)data,
2810 data_len, qca_wlan_vendor_ll_set_policy))
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2813 return -EINVAL;
2814 }
2815 if (!tb_vendor
2816 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2817 {
2818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2819 return -EINVAL;
2820 }
2821 if (!tb_vendor[
2822 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2823 {
2824 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2825 return -EINVAL;
2826 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302827 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302828 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302829
Dino Mycledf0a5d92014-07-04 09:41:55 +05302830 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302831 nla_get_u32(
2832 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2833
Dino Mycledf0a5d92014-07-04 09:41:55 +05302834 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302835 nla_get_u32(
2836 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2837
Dino Mycled3d50022014-07-07 12:58:25 +05302838 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2839 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840
2841
2842 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302843 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2844 "Statistics Gathering = %d ",
2845 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2846 linkLayerStatsSetReq.mpduSizeThreshold,
2847 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302848
2849 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2850 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302851 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 {
2853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2854 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302855 return -EINVAL;
2856
2857 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302858
Sunil Duttc69bccb2014-05-26 21:30:20 +05302859 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302860 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302861 {
2862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2863 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302864 return -EINVAL;
2865 }
2866
2867 pAdapter->isLinkLayerStatsSet = 1;
2868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302869 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302870 return 0;
2871}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302872static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2873 struct wireless_dev *wdev,
2874 const void *data,
2875 int data_len)
2876{
2877 int ret = 0;
2878
2879 vos_ssr_protect(__func__);
2880 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2881 vos_ssr_unprotect(__func__);
2882
2883 return ret;
2884}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302885
2886const struct
2887nla_policy
2888qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2889{
2890 /* Unsigned 32bit value provided by the caller issuing the GET stats
2891 * command. When reporting
2892 * the stats results, the driver uses the same value to indicate
2893 * which GET request the results
2894 * correspond to.
2895 */
2896 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2897
2898 /* Unsigned 32bit value . bit mask to identify what statistics are
2899 requested for retrieval */
2900 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2901};
2902
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302903static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2904 struct wireless_dev *wdev,
2905 const void *data,
2906 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302907{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302908 unsigned long rc;
2909 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302910 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2911 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302912 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302913 struct net_device *dev = wdev->netdev;
2914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302915 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302916 int status;
2917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302918 ENTER();
2919
Sunil Duttc69bccb2014-05-26 21:30:20 +05302920 status = wlan_hdd_validate_context(pHddCtx);
2921 if (0 != status)
2922 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302923 return -EINVAL ;
2924 }
2925
2926 if (NULL == pAdapter)
2927 {
2928 hddLog(VOS_TRACE_LEVEL_FATAL,
2929 "%s: HDD adapter is Null", __func__);
2930 return -ENODEV;
2931 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302932
2933 if (pHddStaCtx == NULL)
2934 {
2935 hddLog(VOS_TRACE_LEVEL_FATAL,
2936 "%s: HddStaCtx is Null", __func__);
2937 return -ENODEV;
2938 }
2939
Dino Mycledf0a5d92014-07-04 09:41:55 +05302940 /* check the LLStats Capability */
2941 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2942 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2943 {
2944 hddLog(VOS_TRACE_LEVEL_ERROR,
2945 FL("Link Layer Statistics not supported by Firmware"));
2946 return -EINVAL;
2947 }
2948
Sunil Duttc69bccb2014-05-26 21:30:20 +05302949
2950 if (!pAdapter->isLinkLayerStatsSet)
2951 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302952 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 "%s: isLinkLayerStatsSet : %d",
2954 __func__, pAdapter->isLinkLayerStatsSet);
2955 return -EINVAL;
2956 }
2957
Mukul Sharma10313ba2015-07-29 19:14:39 +05302958 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2959 {
2960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2961 "%s: Roaming in progress, so unable to proceed this request", __func__);
2962 return -EBUSY;
2963 }
2964
Sunil Duttc69bccb2014-05-26 21:30:20 +05302965 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2966 (struct nlattr *)data,
2967 data_len, qca_wlan_vendor_ll_get_policy))
2968 {
2969 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2970 return -EINVAL;
2971 }
2972
2973 if (!tb_vendor
2974 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2977 return -EINVAL;
2978 }
2979
2980 if (!tb_vendor
2981 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2982 {
2983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2984 return -EINVAL;
2985 }
2986
Sunil Duttc69bccb2014-05-26 21:30:20 +05302987
Dino Mycledf0a5d92014-07-04 09:41:55 +05302988 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302989 nla_get_u32( tb_vendor[
2990 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302991 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302992 nla_get_u32( tb_vendor[
2993 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2994
Dino Mycled3d50022014-07-07 12:58:25 +05302995 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2996 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302997
2998 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302999 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
3000 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303001 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303002
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303003 spin_lock(&hdd_context_lock);
3004 context = &pHddCtx->ll_stats_context;
3005 context->request_id = linkLayerStatsGetReq.reqId;
3006 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3007 INIT_COMPLETION(context->response_event);
3008 spin_unlock(&hdd_context_lock);
3009
Sunil Duttc69bccb2014-05-26 21:30:20 +05303010 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303011 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 {
3013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3014 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303015 return -EINVAL;
3016 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303017
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303018 rc = wait_for_completion_timeout(&context->response_event,
3019 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3020 if (!rc)
3021 {
3022 hddLog(LOGE,
3023 FL("Target response timed out request id %d request bitmap 0x%x"),
3024 context->request_id, context->request_bitmap);
3025 return -ETIMEDOUT;
3026 }
3027
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303028 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303029 return 0;
3030}
3031
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303032static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3033 struct wireless_dev *wdev,
3034 const void *data,
3035 int data_len)
3036{
3037 int ret = 0;
3038
3039 vos_ssr_protect(__func__);
3040 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3041 vos_ssr_unprotect(__func__);
3042
3043 return ret;
3044}
3045
Sunil Duttc69bccb2014-05-26 21:30:20 +05303046const struct
3047nla_policy
3048qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3049{
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3051 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3052 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3053 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3054};
3055
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303056static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3057 struct wireless_dev *wdev,
3058 const void *data,
3059 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060{
3061 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3062 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303063 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303064 struct net_device *dev = wdev->netdev;
3065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3066 u32 statsClearReqMask;
3067 u8 stopReq;
3068 int status;
3069
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303070 ENTER();
3071
Sunil Duttc69bccb2014-05-26 21:30:20 +05303072 status = wlan_hdd_validate_context(pHddCtx);
3073 if (0 != status)
3074 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303075 return -EINVAL;
3076 }
3077
3078 if (NULL == pAdapter)
3079 {
3080 hddLog(VOS_TRACE_LEVEL_FATAL,
3081 "%s: HDD adapter is Null", __func__);
3082 return -ENODEV;
3083 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303084 /* check the LLStats Capability */
3085 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3086 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3087 {
3088 hddLog(VOS_TRACE_LEVEL_ERROR,
3089 FL("Enable LLStats Capability"));
3090 return -EINVAL;
3091 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303092
3093 if (!pAdapter->isLinkLayerStatsSet)
3094 {
3095 hddLog(VOS_TRACE_LEVEL_FATAL,
3096 "%s: isLinkLayerStatsSet : %d",
3097 __func__, pAdapter->isLinkLayerStatsSet);
3098 return -EINVAL;
3099 }
3100
3101 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3102 (struct nlattr *)data,
3103 data_len, qca_wlan_vendor_ll_clr_policy))
3104 {
3105 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3106 return -EINVAL;
3107 }
3108
3109 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3110
3111 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3112 {
3113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3114 return -EINVAL;
3115
3116 }
3117
Sunil Duttc69bccb2014-05-26 21:30:20 +05303118
Dino Mycledf0a5d92014-07-04 09:41:55 +05303119 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120 nla_get_u32(
3121 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3122
Dino Mycledf0a5d92014-07-04 09:41:55 +05303123 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303124 nla_get_u8(
3125 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3126
3127 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303128 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303129
Dino Mycled3d50022014-07-07 12:58:25 +05303130 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3131 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303132
3133 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303134 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3135 "statsClearReqMask = 0x%X, stopReq = %d",
3136 linkLayerStatsClearReq.reqId,
3137 linkLayerStatsClearReq.macAddr,
3138 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303139 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303140
3141 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303142 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303143 {
3144 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303145 hdd_station_ctx_t *pHddStaCtx;
3146
3147 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3148 if (VOS_STATUS_SUCCESS !=
3149 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3150 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3151 {
3152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3153 "WLANTL_ClearInterfaceStats Failed", __func__);
3154 return -EINVAL;
3155 }
3156 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3157 (statsClearReqMask & WIFI_STATS_IFACE)) {
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3159 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3160 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3161 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3162 }
3163
Sunil Duttc69bccb2014-05-26 21:30:20 +05303164 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3165 2 * sizeof(u32) +
3166 NLMSG_HDRLEN);
3167
3168 if (temp_skbuff != NULL)
3169 {
3170
3171 if (nla_put_u32(temp_skbuff,
3172 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3173 statsClearReqMask) ||
3174 nla_put_u32(temp_skbuff,
3175 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3176 stopReq))
3177 {
3178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3179 kfree_skb(temp_skbuff);
3180 return -EINVAL;
3181 }
3182 /* If the ask is to stop the stats collection as part of clear
3183 * (stopReq = 1) , ensure that no further requests of get
3184 * go to the firmware by having isLinkLayerStatsSet set to 0.
3185 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303186 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303187 * case the firmware is just asked to clear the statistics.
3188 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303189 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303190 pAdapter->isLinkLayerStatsSet = 0;
3191 return cfg80211_vendor_cmd_reply(temp_skbuff);
3192 }
3193 return -ENOMEM;
3194 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303195
3196 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303197 return -EINVAL;
3198}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303199static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3200 struct wireless_dev *wdev,
3201 const void *data,
3202 int data_len)
3203{
3204 int ret = 0;
3205
3206 vos_ssr_protect(__func__);
3207 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3208 vos_ssr_unprotect(__func__);
3209
3210 return ret;
3211
3212
3213}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303214#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3215
Dino Mycle6fb96c12014-06-10 11:52:40 +05303216#ifdef WLAN_FEATURE_EXTSCAN
3217static const struct nla_policy
3218wlan_hdd_extscan_config_policy
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3220{
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3222 { .type = NLA_U32 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3224 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3226 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3232
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3237 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3239 { .type = NLA_U32 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3241 { .type = NLA_U32 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3243 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3245 { .type = NLA_U32 },
3246 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3247 { .type = NLA_U32 },
3248 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3249 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303250 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3251 { .type = NLA_U8 },
3252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303253 { .type = NLA_U8 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3255 { .type = NLA_U8 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3257 { .type = NLA_U8 },
3258
3259 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3260 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3262 .type = NLA_UNSPEC,
3263 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3265 { .type = NLA_S32 },
3266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3267 { .type = NLA_S32 },
3268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3269 { .type = NLA_U32 },
3270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3271 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303272 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3273 { .type = NLA_U32 },
3274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3275 { .type = NLA_BINARY,
3276 .len = IEEE80211_MAX_SSID_LEN + 1 },
3277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3280 { .type = NLA_U32 },
3281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3282 { .type = NLA_U8 },
3283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3284 { .type = NLA_S32 },
3285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3286 { .type = NLA_S32 },
3287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3288 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303289};
3290
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291/**
3292 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3293 * @ctx: hdd global context
3294 * @data: capabilities data
3295 *
3296 * Return: none
3297 */
3298static void
3299wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303300{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303301 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303303 tSirEXTScanCapabilitiesEvent *data =
3304 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303306 ENTER();
3307
3308 if (wlan_hdd_validate_context(pHddCtx))
3309 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303310 return;
3311 }
3312
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303313 if (!pMsg)
3314 {
3315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3316 return;
3317 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303318
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 vos_spin_lock_acquire(&hdd_context_lock);
3320
3321 context = &pHddCtx->ext_scan_context;
3322 /* validate response received from target*/
3323 if (context->request_id != data->requestId)
3324 {
3325 vos_spin_lock_release(&hdd_context_lock);
3326 hddLog(LOGE,
3327 FL("Target response id did not match: request_id %d resposne_id %d"),
3328 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303329 return;
3330 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303331 else
3332 {
3333 context->capability_response = *data;
3334 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 }
3336
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303337 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338
Dino Mycle6fb96c12014-06-10 11:52:40 +05303339 return;
3340}
3341
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303342/*
3343 * define short names for the global vendor params
3344 * used by wlan_hdd_send_ext_scan_capability()
3345 */
3346#define PARAM_REQUEST_ID \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3348#define PARAM_STATUS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3350#define MAX_SCAN_CACHE_SIZE \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3352#define MAX_SCAN_BUCKETS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3354#define MAX_AP_CACHE_PER_SCAN \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3356#define MAX_RSSI_SAMPLE_SIZE \
3357 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3358#define MAX_SCAN_RPT_THRHOLD \
3359 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3360#define MAX_HOTLIST_BSSIDS \
3361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3362#define MAX_BSSID_HISTORY_ENTRIES \
3363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3364#define MAX_HOTLIST_SSIDS \
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303366#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303368
3369static int wlan_hdd_send_ext_scan_capability(void *ctx)
3370{
3371 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3372 struct sk_buff *skb = NULL;
3373 int ret;
3374 tSirEXTScanCapabilitiesEvent *data;
3375 tANI_U32 nl_buf_len;
3376
3377 ret = wlan_hdd_validate_context(pHddCtx);
3378 if (0 != ret)
3379 {
3380 return ret;
3381 }
3382
3383 data = &(pHddCtx->ext_scan_context.capability_response);
3384
3385 nl_buf_len = NLMSG_HDRLEN;
3386 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3387 (sizeof(data->status) + NLA_HDRLEN) +
3388 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3389 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3390 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3391 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3392 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3393 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3394 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3395 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3396
3397 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3398
3399 if (!skb)
3400 {
3401 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3402 return -ENOMEM;
3403 }
3404
3405 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3406 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3407 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3408 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3409 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3410 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3411 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3412 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3413
3414 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3415 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3416 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3417 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3418 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3419 data->maxApPerScan) ||
3420 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3421 data->maxRssiSampleSize) ||
3422 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3423 data->maxScanReportingThreshold) ||
3424 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3425 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3426 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303427 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3428 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303429 {
3430 hddLog(LOGE, FL("nla put fail"));
3431 goto nla_put_failure;
3432 }
3433
3434 cfg80211_vendor_cmd_reply(skb);
3435 return 0;
3436
3437nla_put_failure:
3438 kfree_skb(skb);
3439 return -EINVAL;;
3440}
3441
3442/*
3443 * done with short names for the global vendor params
3444 * used by wlan_hdd_send_ext_scan_capability()
3445 */
3446#undef PARAM_REQUEST_ID
3447#undef PARAM_STATUS
3448#undef MAX_SCAN_CACHE_SIZE
3449#undef MAX_SCAN_BUCKETS
3450#undef MAX_AP_CACHE_PER_SCAN
3451#undef MAX_RSSI_SAMPLE_SIZE
3452#undef MAX_SCAN_RPT_THRHOLD
3453#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303454#undef MAX_BSSID_HISTORY_ENTRIES
3455#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303456
3457static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3458{
3459 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3460 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303462 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303464 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303467 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303469 if (!pMsg)
3470 {
3471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 return;
3473 }
3474
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3476 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3477
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303478 context = &pHddCtx->ext_scan_context;
3479 spin_lock(&hdd_context_lock);
3480 if (context->request_id == pData->requestId) {
3481 context->response_status = pData->status ? -EINVAL : 0;
3482 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303484 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485
3486 /*
3487 * Store the Request ID for comparing with the requestID obtained
3488 * in other requests.HDD shall return a failure is the extscan_stop
3489 * request is issued with a different requestId as that of the
3490 * extscan_start request. Also, This requestId shall be used while
3491 * indicating the full scan results to the upper layers.
3492 * The requestId is stored with the assumption that the firmware
3493 * shall return the ext scan start request's requestId in ext scan
3494 * start response.
3495 */
3496 if (pData->status == 0)
3497 pMac->sme.extScanStartReqId = pData->requestId;
3498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303499 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303501}
3502
3503
3504static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3505{
3506 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3507 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303508 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303510 ENTER();
3511
3512 if (wlan_hdd_validate_context(pHddCtx)){
3513 return;
3514 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303515
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303516 if (!pMsg)
3517 {
3518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 return;
3520 }
3521
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303522 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3523 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303525 context = &pHddCtx->ext_scan_context;
3526 spin_lock(&hdd_context_lock);
3527 if (context->request_id == pData->requestId) {
3528 context->response_status = pData->status ? -EINVAL : 0;
3529 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303531 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535}
3536
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3538 void *pMsg)
3539{
3540 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 tpSirEXTScanSetBssidHotListRspParams pData =
3542 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303543 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303545 ENTER();
3546
3547 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548 return;
3549 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303550
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303551 if (!pMsg)
3552 {
3553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3554 return;
3555 }
3556
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303557 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3558 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303559
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303560 context = &pHddCtx->ext_scan_context;
3561 spin_lock(&hdd_context_lock);
3562 if (context->request_id == pData->requestId) {
3563 context->response_status = pData->status ? -EINVAL : 0;
3564 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303566 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303569 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303570}
3571
3572static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3573 void *pMsg)
3574{
3575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 tpSirEXTScanResetBssidHotlistRspParams pData =
3577 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303578 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303580 ENTER();
3581
3582 if (wlan_hdd_validate_context(pHddCtx)) {
3583 return;
3584 }
3585 if (!pMsg)
3586 {
3587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303588 return;
3589 }
3590
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303591 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3592 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303593
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303594 context = &pHddCtx->ext_scan_context;
3595 spin_lock(&hdd_context_lock);
3596 if (context->request_id == pData->requestId) {
3597 context->response_status = pData->status ? -EINVAL : 0;
3598 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303600 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303602 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604}
3605
Dino Mycle6fb96c12014-06-10 11:52:40 +05303606static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3607 void *pMsg)
3608{
3609 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3610 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303611 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303612 tANI_S32 totalResults;
3613 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3615 struct hdd_ext_scan_context *context;
3616 bool ignore_cached_results = false;
3617 tExtscanCachedScanResult *result;
3618 struct nlattr *nla_results;
3619 tANI_U16 ieLength= 0;
3620 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303622 ENTER();
3623
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303624 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303627 if (!pMsg)
3628 {
3629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3630 return;
3631 }
3632
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303633 spin_lock(&hdd_context_lock);
3634 context = &pHddCtx->ext_scan_context;
3635 ignore_cached_results = context->ignore_cached_results;
3636 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303638 if (ignore_cached_results) {
3639 hddLog(LOGE,
3640 FL("Ignore the cached results received after timeout"));
3641 return;
3642 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303644 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3645 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303646
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303647 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303648
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3650 scan_id_index++) {
3651 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303653 totalResults = result->num_results;
3654 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3655 result->scan_id, result->flags, totalResults);
3656 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303658 do{
3659 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3660 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3661 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303663 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3664 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3665
3666 if (!skb) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR,
3668 FL("cfg80211_vendor_event_alloc failed"));
3669 return;
3670 }
3671
3672 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3673
3674 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3675 pData->requestId) ||
3676 nla_put_u32(skb,
3677 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3678 resultsPerEvent)) {
3679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3680 goto fail;
3681 }
3682 if (nla_put_u8(skb,
3683 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3684 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 {
3686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3687 goto fail;
3688 }
3689
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303690 if (nla_put_u32(skb,
3691 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3692 result->scan_id)) {
3693 hddLog(LOGE, FL("put fail"));
3694 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303696
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303697 nla_results = nla_nest_start(skb,
3698 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3699 if (!nla_results)
3700 goto fail;
3701
3702 if (resultsPerEvent) {
3703 struct nlattr *aps;
3704 struct nlattr *nla_result;
3705
3706 nla_result = nla_nest_start(skb, scan_id_index);
3707 if(!nla_result)
3708 goto fail;
3709
3710 if (nla_put_u32(skb,
3711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3712 result->scan_id) ||
3713 nla_put_u32(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3715 result->flags) ||
3716 nla_put_u32(skb,
3717 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3718 totalResults)) {
3719 hddLog(LOGE, FL("put fail"));
3720 goto fail;
3721 }
3722
3723 aps = nla_nest_start(skb,
3724 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3725 if (!aps)
3726 {
3727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3728 goto fail;
3729 }
3730
3731 head_ptr = (tpSirWifiScanResult) &(result->ap);
3732
3733 for (j = 0; j < resultsPerEvent; j++, i++) {
3734 struct nlattr *ap;
3735 pSirWifiScanResult = head_ptr + i;
3736
3737 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303738 * Firmware returns timestamp from extscan_start till
3739 * BSSID was cached (in micro seconds). Add this with
3740 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303741 * to derive the time since boot when the
3742 * BSSID was cached.
3743 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303744 pSirWifiScanResult->ts +=
3745 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303746 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3747 "Ssid (%s)"
3748 "Bssid: %pM "
3749 "Channel (%u)"
3750 "Rssi (%d)"
3751 "RTT (%u)"
3752 "RTT_SD (%u)"
3753 "Beacon Period %u"
3754 "Capability 0x%x "
3755 "Ie length %d",
3756 i,
3757 pSirWifiScanResult->ts,
3758 pSirWifiScanResult->ssid,
3759 pSirWifiScanResult->bssid,
3760 pSirWifiScanResult->channel,
3761 pSirWifiScanResult->rssi,
3762 pSirWifiScanResult->rtt,
3763 pSirWifiScanResult->rtt_sd,
3764 pSirWifiScanResult->beaconPeriod,
3765 pSirWifiScanResult->capability,
3766 ieLength);
3767
3768 ap = nla_nest_start(skb, j + 1);
3769 if (!ap)
3770 {
3771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3772 goto fail;
3773 }
3774
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303775 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303776 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3777 pSirWifiScanResult->ts) )
3778 {
3779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3780 goto fail;
3781 }
3782 if (nla_put(skb,
3783 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3784 sizeof(pSirWifiScanResult->ssid),
3785 pSirWifiScanResult->ssid) )
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3788 goto fail;
3789 }
3790 if (nla_put(skb,
3791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3792 sizeof(pSirWifiScanResult->bssid),
3793 pSirWifiScanResult->bssid) )
3794 {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3796 goto fail;
3797 }
3798 if (nla_put_u32(skb,
3799 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3800 pSirWifiScanResult->channel) )
3801 {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3803 goto fail;
3804 }
3805 if (nla_put_s32(skb,
3806 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3807 pSirWifiScanResult->rssi) )
3808 {
3809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3810 goto fail;
3811 }
3812 if (nla_put_u32(skb,
3813 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3814 pSirWifiScanResult->rtt) )
3815 {
3816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3817 goto fail;
3818 }
3819 if (nla_put_u32(skb,
3820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3821 pSirWifiScanResult->rtt_sd))
3822 {
3823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3824 goto fail;
3825 }
3826 if (nla_put_u32(skb,
3827 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3828 pSirWifiScanResult->beaconPeriod))
3829 {
3830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3831 goto fail;
3832 }
3833 if (nla_put_u32(skb,
3834 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3835 pSirWifiScanResult->capability))
3836 {
3837 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3838 goto fail;
3839 }
3840 if (nla_put_u32(skb,
3841 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3842 ieLength))
3843 {
3844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3845 goto fail;
3846 }
3847
3848 if (ieLength)
3849 if (nla_put(skb,
3850 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3851 ieLength, ie)) {
3852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3853 goto fail;
3854 }
3855
3856 nla_nest_end(skb, ap);
3857 }
3858 nla_nest_end(skb, aps);
3859 nla_nest_end(skb, nla_result);
3860 }
3861
3862 nla_nest_end(skb, nla_results);
3863
3864 cfg80211_vendor_cmd_reply(skb);
3865
3866 } while (totalResults > 0);
3867 }
3868
3869 if (!pData->moreData) {
3870 spin_lock(&hdd_context_lock);
3871 context->response_status = 0;
3872 complete(&context->response_event);
3873 spin_unlock(&hdd_context_lock);
3874 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303876 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303877 return;
3878fail:
3879 kfree_skb(skb);
3880 return;
3881}
3882
3883static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3884 void *pMsg)
3885{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303886 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303887 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3888 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303889 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303891 ENTER();
3892
3893 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303894 hddLog(LOGE,
3895 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303896 return;
3897 }
3898 if (!pMsg)
3899 {
3900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 return;
3902 }
3903
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303904 if (pData->bss_found)
3905 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3906 else
3907 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3908
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3911 NULL,
3912#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303914 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
3916 if (!skb) {
3917 hddLog(VOS_TRACE_LEVEL_ERROR,
3918 FL("cfg80211_vendor_event_alloc failed"));
3919 return;
3920 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303922 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3923 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3924 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3925 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3926
3927 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303928 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3929 "Ssid (%s) "
3930 "Bssid (" MAC_ADDRESS_STR ") "
3931 "Channel (%u) "
3932 "Rssi (%d) "
3933 "RTT (%u) "
3934 "RTT_SD (%u) ",
3935 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303936 pData->bssHotlist[i].ts,
3937 pData->bssHotlist[i].ssid,
3938 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3939 pData->bssHotlist[i].channel,
3940 pData->bssHotlist[i].rssi,
3941 pData->bssHotlist[i].rtt,
3942 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303943 }
3944
3945 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3946 pData->requestId) ||
3947 nla_put_u32(skb,
3948 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3951 goto fail;
3952 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303953 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303954 struct nlattr *aps;
3955
3956 aps = nla_nest_start(skb,
3957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3958 if (!aps)
3959 goto fail;
3960
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303962 struct nlattr *ap;
3963
3964 ap = nla_nest_start(skb, i + 1);
3965 if (!ap)
3966 goto fail;
3967
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303968 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303970 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303971 nla_put(skb,
3972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303973 sizeof(pData->bssHotlist[i].ssid),
3974 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303975 nla_put(skb,
3976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303977 sizeof(pData->bssHotlist[i].bssid),
3978 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 nla_put_u32(skb,
3980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303981 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 nla_put_s32(skb,
3983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303984 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303987 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303988 nla_put_u32(skb,
3989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303990 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303991 goto fail;
3992
3993 nla_nest_end(skb, ap);
3994 }
3995 nla_nest_end(skb, aps);
3996
3997 if (nla_put_u8(skb,
3998 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3999 pData->moreData))
4000 goto fail;
4001 }
4002
4003 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304004 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005 return;
4006
4007fail:
4008 kfree_skb(skb);
4009 return;
4010
4011}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304012
4013static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4014 void *pMsg)
4015{
4016 struct sk_buff *skb;
4017 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4018 tpSirWifiFullScanResultEvent pData =
4019 (tpSirWifiFullScanResultEvent) (pMsg);
4020
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304021 ENTER();
4022
4023 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304024 hddLog(LOGE,
4025 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304026 return;
4027 }
4028 if (!pMsg)
4029 {
4030 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 return;
4032 }
4033
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304034 /*
4035 * If the full scan result including IE data exceeds NL 4K size
4036 * limitation, drop that beacon/probe rsp frame.
4037 */
4038 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4039 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4040 return;
4041 }
4042
Dino Mycle6fb96c12014-06-10 11:52:40 +05304043 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4045 NULL,
4046#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304047 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4048 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4049 GFP_KERNEL);
4050
4051 if (!skb) {
4052 hddLog(VOS_TRACE_LEVEL_ERROR,
4053 FL("cfg80211_vendor_event_alloc failed"));
4054 return;
4055 }
4056
Dino Mycle6fb96c12014-06-10 11:52:40 +05304057 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4059 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4060 "Ssid (%s)"
4061 "Bssid (" MAC_ADDRESS_STR ")"
4062 "Channel (%u)"
4063 "Rssi (%d)"
4064 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304065 "RTT_SD (%u)"
4066 "Bcn Period %d"
4067 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304068 pData->ap.ts,
4069 pData->ap.ssid,
4070 MAC_ADDR_ARRAY(pData->ap.bssid),
4071 pData->ap.channel,
4072 pData->ap.rssi,
4073 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304074 pData->ap.rtt_sd,
4075 pData->ap.beaconPeriod,
4076 pData->ap.capability);
4077
Dino Mycle6fb96c12014-06-10 11:52:40 +05304078 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4079 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4080 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304081 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4083 pData->ap.ts) ||
4084 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4085 sizeof(pData->ap.ssid),
4086 pData->ap.ssid) ||
4087 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4088 WNI_CFG_BSSID_LEN,
4089 pData->ap.bssid) ||
4090 nla_put_u32(skb,
4091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4092 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304093 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304094 pData->ap.rssi) ||
4095 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4096 pData->ap.rtt) ||
4097 nla_put_u32(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4099 pData->ap.rtt_sd) ||
4100 nla_put_u16(skb,
4101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4102 pData->ap.beaconPeriod) ||
4103 nla_put_u16(skb,
4104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4105 pData->ap.capability) ||
4106 nla_put_u32(skb,
4107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304108 pData->ieLength) ||
4109 nla_put_u8(skb,
4110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4111 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304112 {
4113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4114 goto nla_put_failure;
4115 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304116
4117 if (pData->ieLength) {
4118 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4119 pData->ieLength,
4120 pData->ie))
4121 {
4122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4123 goto nla_put_failure;
4124 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304125 }
4126
4127 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304128 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304129 return;
4130
4131nla_put_failure:
4132 kfree_skb(skb);
4133 return;
4134}
4135
4136static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4137 void *pMsg)
4138{
4139 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4140 struct sk_buff *skb = NULL;
4141 tpSirEXTScanResultsAvailableIndParams pData =
4142 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304144 ENTER();
4145
4146 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304147 hddLog(LOGE,
4148 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304149 return;
4150 }
4151 if (!pMsg)
4152 {
4153 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304154 return;
4155 }
4156
4157 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4159 NULL,
4160#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304161 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4162 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4163 GFP_KERNEL);
4164
4165 if (!skb) {
4166 hddLog(VOS_TRACE_LEVEL_ERROR,
4167 FL("cfg80211_vendor_event_alloc failed"));
4168 return;
4169 }
4170
Dino Mycle6fb96c12014-06-10 11:52:40 +05304171 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4172 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4173 pData->numResultsAvailable);
4174 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4175 pData->requestId) ||
4176 nla_put_u32(skb,
4177 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4178 pData->numResultsAvailable)) {
4179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4180 goto nla_put_failure;
4181 }
4182
4183 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304184 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304185 return;
4186
4187nla_put_failure:
4188 kfree_skb(skb);
4189 return;
4190}
4191
4192static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4193{
4194 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4195 struct sk_buff *skb = NULL;
4196 tpSirEXTScanProgressIndParams pData =
4197 (tpSirEXTScanProgressIndParams) pMsg;
4198
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304199 ENTER();
4200
4201 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304202 hddLog(LOGE,
4203 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304204 return;
4205 }
4206 if (!pMsg)
4207 {
4208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209 return;
4210 }
4211
4212 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304213#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4214 NULL,
4215#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304216 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4217 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4218 GFP_KERNEL);
4219
4220 if (!skb) {
4221 hddLog(VOS_TRACE_LEVEL_ERROR,
4222 FL("cfg80211_vendor_event_alloc failed"));
4223 return;
4224 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304225 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4227 pData->extScanEventType);
4228 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4229 pData->status);
4230
4231 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4232 pData->extScanEventType) ||
4233 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4235 pData->requestId) ||
4236 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304237 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4238 pData->status)) {
4239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4240 goto nla_put_failure;
4241 }
4242
4243 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304244 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 return;
4246
4247nla_put_failure:
4248 kfree_skb(skb);
4249 return;
4250}
4251
4252void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4253 void *pMsg)
4254{
4255 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4256
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304257 ENTER();
4258
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260 return;
4261 }
4262
4263 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4264
4265
4266 switch(evType) {
4267 case SIR_HAL_EXTSCAN_START_RSP:
4268 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4269 break;
4270
4271 case SIR_HAL_EXTSCAN_STOP_RSP:
4272 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4273 break;
4274 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4275 /* There is no need to send this response to upper layer
4276 Just log the message */
4277 hddLog(VOS_TRACE_LEVEL_INFO,
4278 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4279 break;
4280 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4281 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4282 break;
4283
4284 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4285 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4286 break;
4287
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304289 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304290 break;
4291 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4292 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4293 break;
4294 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4295 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4296 break;
4297 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4298 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4299 break;
4300 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4301 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4302 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304303 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4304 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4305 break;
4306 default:
4307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4308 break;
4309 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304310 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304311}
4312
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304313static bool wlan_hdd_is_extscan_supported(hdd_adapter_t *adapter,
4314 hdd_context_t *hdd_ctx)
4315{
4316 int status;
4317
4318 status = wlan_hdd_validate_context(hdd_ctx);
4319 if (status)
4320 return false;
4321
4322 if (!adapter) {
4323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid adapter"));
4324 return false;
4325 }
4326
4327 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
4328 hddLog(VOS_TRACE_LEVEL_INFO,
4329 FL("ext scans only supported on STA ifaces"));
4330 return false;
4331 }
4332
4333 if (VOS_FTM_MODE == hdd_get_conparam()) {
4334 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4335 return false;
4336 }
4337
4338 /* check the EXTScan Capability */
4339 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4340 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4341 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR,
4343 FL("EXTScan not enabled/supported by Firmware"));
4344 return false;
4345 }
4346 return true;
4347}
4348
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304349static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4350 struct wireless_dev *wdev,
4351 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352{
Dino Myclee8843b32014-07-04 14:21:45 +05304353 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354 struct net_device *dev = wdev->netdev;
4355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4356 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4357 struct nlattr
4358 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4359 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304360 struct hdd_ext_scan_context *context;
4361 unsigned long rc;
4362 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304364 ENTER();
4365
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304366 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304367 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304368
Dino Mycle6fb96c12014-06-10 11:52:40 +05304369 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4370 data, dataLen,
4371 wlan_hdd_extscan_config_policy)) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4373 return -EINVAL;
4374 }
4375
4376 /* Parse and fetch request Id */
4377 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4379 return -EINVAL;
4380 }
4381
Dino Myclee8843b32014-07-04 14:21:45 +05304382 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304383 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304384 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304385
Dino Myclee8843b32014-07-04 14:21:45 +05304386 reqMsg.sessionId = pAdapter->sessionId;
4387 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304389 vos_spin_lock_acquire(&hdd_context_lock);
4390 context = &pHddCtx->ext_scan_context;
4391 context->request_id = reqMsg.requestId;
4392 INIT_COMPLETION(context->response_event);
4393 vos_spin_lock_release(&hdd_context_lock);
4394
Dino Myclee8843b32014-07-04 14:21:45 +05304395 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 if (!HAL_STATUS_SUCCESS(status)) {
4397 hddLog(VOS_TRACE_LEVEL_ERROR,
4398 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399 return -EINVAL;
4400 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304401
4402 rc = wait_for_completion_timeout(&context->response_event,
4403 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4404 if (!rc) {
4405 hddLog(LOGE, FL("Target response timed out"));
4406 return -ETIMEDOUT;
4407 }
4408
4409 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4410 if (ret)
4411 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4412
4413 return ret;
4414
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304415 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304416 return 0;
4417}
4418
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304419static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4420 struct wireless_dev *wdev,
4421 const void *data, int dataLen)
4422{
4423 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304424
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304425 vos_ssr_protect(__func__);
4426 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4427 vos_ssr_unprotect(__func__);
4428
4429 return ret;
4430}
4431
4432static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4433 struct wireless_dev *wdev,
4434 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304435{
Dino Myclee8843b32014-07-04 14:21:45 +05304436 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304437 struct net_device *dev = wdev->netdev;
4438 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4439 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4440 struct nlattr
4441 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4442 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304443 struct hdd_ext_scan_context *context;
4444 unsigned long rc;
4445 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304447 ENTER();
4448
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304449 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304450 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304451
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4453 data, dataLen,
4454 wlan_hdd_extscan_config_policy)) {
4455 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4456 return -EINVAL;
4457 }
4458 /* Parse and fetch request Id */
4459 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4461 return -EINVAL;
4462 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304463
Dino Myclee8843b32014-07-04 14:21:45 +05304464 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304465 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4466
Dino Myclee8843b32014-07-04 14:21:45 +05304467 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304468
Dino Myclee8843b32014-07-04 14:21:45 +05304469 reqMsg.sessionId = pAdapter->sessionId;
4470 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304471
4472 /* Parse and fetch flush parameter */
4473 if (!tb
4474 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4475 {
4476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4477 goto failed;
4478 }
Dino Myclee8843b32014-07-04 14:21:45 +05304479 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304480 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4481
Dino Myclee8843b32014-07-04 14:21:45 +05304482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304483
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304484 spin_lock(&hdd_context_lock);
4485 context = &pHddCtx->ext_scan_context;
4486 context->request_id = reqMsg.requestId;
4487 context->ignore_cached_results = false;
4488 INIT_COMPLETION(context->response_event);
4489 spin_unlock(&hdd_context_lock);
4490
Dino Myclee8843b32014-07-04 14:21:45 +05304491 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304492 if (!HAL_STATUS_SUCCESS(status)) {
4493 hddLog(VOS_TRACE_LEVEL_ERROR,
4494 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495 return -EINVAL;
4496 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304497
4498 rc = wait_for_completion_timeout(&context->response_event,
4499 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4500 if (!rc) {
4501 hddLog(LOGE, FL("Target response timed out"));
4502 retval = -ETIMEDOUT;
4503 spin_lock(&hdd_context_lock);
4504 context->ignore_cached_results = true;
4505 spin_unlock(&hdd_context_lock);
4506 } else {
4507 spin_lock(&hdd_context_lock);
4508 retval = context->response_status;
4509 spin_unlock(&hdd_context_lock);
4510 }
4511
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304512 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304513 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304514
4515failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304516 return -EINVAL;
4517}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304518static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4519 struct wireless_dev *wdev,
4520 const void *data, int dataLen)
4521{
4522 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304523
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304524 vos_ssr_protect(__func__);
4525 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4526 vos_ssr_unprotect(__func__);
4527
4528 return ret;
4529}
4530
4531static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304533 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304534{
4535 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4536 struct net_device *dev = wdev->netdev;
4537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4538 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4539 struct nlattr
4540 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4541 struct nlattr
4542 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4543 struct nlattr *apTh;
4544 eHalStatus status;
4545 tANI_U8 i = 0;
4546 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304547 struct hdd_ext_scan_context *context;
4548 tANI_U32 request_id;
4549 unsigned long rc;
4550 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304552 ENTER();
4553
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304554 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304555 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304556
Dino Mycle6fb96c12014-06-10 11:52:40 +05304557 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4558 data, dataLen,
4559 wlan_hdd_extscan_config_policy)) {
4560 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4561 return -EINVAL;
4562 }
4563
4564 /* Parse and fetch request Id */
4565 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4567 return -EINVAL;
4568 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304569 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4570 vos_mem_malloc(sizeof(*pReqMsg));
4571 if (!pReqMsg) {
4572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4573 return -ENOMEM;
4574 }
4575
Dino Myclee8843b32014-07-04 14:21:45 +05304576
Dino Mycle6fb96c12014-06-10 11:52:40 +05304577 pReqMsg->requestId = nla_get_u32(
4578 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4579 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4580
4581 /* Parse and fetch number of APs */
4582 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4584 goto fail;
4585 }
4586
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304587 /* Parse and fetch lost ap sample size */
4588 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4589 hddLog(LOGE, FL("attr lost ap sample size failed"));
4590 goto fail;
4591 }
4592
4593 pReqMsg->lostBssidSampleSize = nla_get_u32(
4594 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4595 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4596
Dino Mycle6fb96c12014-06-10 11:52:40 +05304597 pReqMsg->sessionId = pAdapter->sessionId;
4598 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4599
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304600 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304601 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304602 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4603 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4604 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4605 goto fail;
4606 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304607 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608
4609 nla_for_each_nested(apTh,
4610 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304611 if (i == pReqMsg->numBssid) {
4612 hddLog(LOGW, FL("Ignoring excess AP"));
4613 break;
4614 }
4615
Dino Mycle6fb96c12014-06-10 11:52:40 +05304616 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4617 nla_data(apTh), nla_len(apTh),
4618 NULL)) {
4619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4620 goto fail;
4621 }
4622
4623 /* Parse and fetch MAC address */
4624 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4626 goto fail;
4627 }
4628 memcpy(pReqMsg->ap[i].bssid, nla_data(
4629 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4630 sizeof(tSirMacAddr));
4631 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4632
4633 /* Parse and fetch low RSSI */
4634 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4636 goto fail;
4637 }
4638 pReqMsg->ap[i].low = nla_get_s32(
4639 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4640 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4641
4642 /* Parse and fetch high RSSI */
4643 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4645 goto fail;
4646 }
4647 pReqMsg->ap[i].high = nla_get_s32(
4648 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4649 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4650 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304651 i++;
4652 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304653
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304654 if (i < pReqMsg->numBssid) {
4655 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4656 i, pReqMsg->numBssid);
4657 pReqMsg->numBssid = i;
4658 }
4659
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304660 context = &pHddCtx->ext_scan_context;
4661 spin_lock(&hdd_context_lock);
4662 INIT_COMPLETION(context->response_event);
4663 context->request_id = request_id = pReqMsg->requestId;
4664 spin_unlock(&hdd_context_lock);
4665
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4667 if (!HAL_STATUS_SUCCESS(status)) {
4668 hddLog(VOS_TRACE_LEVEL_ERROR,
4669 FL("sme_SetBssHotlist failed(err=%d)"), status);
4670 vos_mem_free(pReqMsg);
4671 return -EINVAL;
4672 }
4673
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304674 /* request was sent -- wait for the response */
4675 rc = wait_for_completion_timeout(&context->response_event,
4676 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4677
4678 if (!rc) {
4679 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4680 retval = -ETIMEDOUT;
4681 } else {
4682 spin_lock(&hdd_context_lock);
4683 if (context->request_id == request_id)
4684 retval = context->response_status;
4685 else
4686 retval = -EINVAL;
4687 spin_unlock(&hdd_context_lock);
4688 }
4689
Dino Myclee8843b32014-07-04 14:21:45 +05304690 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304691 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304692 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304693
4694fail:
4695 vos_mem_free(pReqMsg);
4696 return -EINVAL;
4697}
4698
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304699static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4700 struct wireless_dev *wdev,
4701 const void *data, int dataLen)
4702{
4703 int ret = 0;
4704
4705 vos_ssr_protect(__func__);
4706 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4707 dataLen);
4708 vos_ssr_unprotect(__func__);
4709
4710 return ret;
4711}
4712
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304713static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304715 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304716{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304717 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4718 struct net_device *dev = wdev->netdev;
4719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4720 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4721 uint8_t num_channels = 0;
4722 uint8_t num_chan_new = 0;
4723 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304725 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304726 tWifiBand wifiBand;
4727 eHalStatus status;
4728 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304729 tANI_U8 i,j,k;
4730 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304731
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304732 ENTER();
4733
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304734 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304736
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4738 data, dataLen,
4739 wlan_hdd_extscan_config_policy)) {
4740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4741 return -EINVAL;
4742 }
4743
4744 /* Parse and fetch request Id */
4745 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4747 return -EINVAL;
4748 }
4749 requestId = nla_get_u32(
4750 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4752
4753 /* Parse and fetch wifi band */
4754 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4755 {
4756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4757 return -EINVAL;
4758 }
4759 wifiBand = nla_get_u32(
4760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4762
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304763 /* Parse and fetch max channels */
4764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4765 {
4766 hddLog(LOGE, FL("attr max channels failed"));
4767 return -EINVAL;
4768 }
4769 maxChannels = nla_get_u32(
4770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4772
Dino Mycle6fb96c12014-06-10 11:52:40 +05304773 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304774 wifiBand, chan_list,
4775 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304776 if (eHAL_STATUS_SUCCESS != status) {
4777 hddLog(VOS_TRACE_LEVEL_ERROR,
4778 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4779 return -EINVAL;
4780 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304781
Agrawal Ashish16abf782016-08-18 22:42:59 +05304782 num_channels = VOS_MIN(num_channels, maxChannels);
4783 num_chan_new = num_channels;
4784 /* remove the indoor only channels if iface is SAP */
4785 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4786 {
4787 num_chan_new = 0;
4788 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304789 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304790 if (wiphy->bands[j] == NULL)
4791 continue;
4792 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4793 if ((chan_list[i] ==
4794 wiphy->bands[j]->channels[k].center_freq) &&
4795 (!(wiphy->bands[j]->channels[k].flags &
4796 IEEE80211_CHAN_INDOOR_ONLY))) {
4797 chan_list[num_chan_new] = chan_list[i];
4798 num_chan_new++;
4799 }
4800 }
4801 }
4802 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304803
Agrawal Ashish16abf782016-08-18 22:42:59 +05304804 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4805 for (i = 0; i < num_chan_new; i++)
4806 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4807 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808
4809 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304810 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304811 NLMSG_HDRLEN);
4812
4813 if (!replySkb) {
4814 hddLog(VOS_TRACE_LEVEL_ERROR,
4815 FL("valid channels: buffer alloc fail"));
4816 return -EINVAL;
4817 }
4818 if (nla_put_u32(replySkb,
4819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304820 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304822 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823
4824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4825 kfree_skb(replySkb);
4826 return -EINVAL;
4827 }
4828
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304829 ret = cfg80211_vendor_cmd_reply(replySkb);
4830
4831 EXIT();
4832 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833}
4834
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304835static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4836 struct wireless_dev *wdev,
4837 const void *data, int dataLen)
4838{
4839 int ret = 0;
4840
4841 vos_ssr_protect(__func__);
4842 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4843 dataLen);
4844 vos_ssr_unprotect(__func__);
4845
4846 return ret;
4847}
4848
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304849static int hdd_extscan_start_fill_bucket_channel_spec(
4850 hdd_context_t *pHddCtx,
4851 tpSirEXTScanStartReqParams pReqMsg,
4852 struct nlattr **tb)
4853{
4854 struct nlattr *bucket[
4855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4856 struct nlattr *channel[
4857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4858 struct nlattr *buckets;
4859 struct nlattr *channels;
4860 int rem1, rem2;
4861 eHalStatus status;
4862 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304863 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304864 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4865 tANI_U32 passive_max_chn_time, active_max_chn_time;
4866
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304867 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304868 bktIndex = 0;
4869
4870 nla_for_each_nested(buckets,
4871 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304872 if (bktIndex >= expected_buckets) {
4873 hddLog(LOGW, FL("ignoring excess buckets"));
4874 break;
4875 }
4876
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304877 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304878 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4879 nla_data(buckets), nla_len(buckets),
4880 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304881 hddLog(LOGE, FL("nla_parse failed"));
4882 return -EINVAL;
4883 }
4884
4885 /* Parse and fetch bucket spec */
4886 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4887 hddLog(LOGE, FL("attr bucket index failed"));
4888 return -EINVAL;
4889 }
4890 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4891 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4892 hddLog(LOG1, FL("Bucket spec Index %d"),
4893 pReqMsg->buckets[bktIndex].bucket);
4894
4895 /* Parse and fetch wifi band */
4896 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4897 hddLog(LOGE, FL("attr wifi band failed"));
4898 return -EINVAL;
4899 }
4900 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4901 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4902 hddLog(LOG1, FL("Wifi band %d"),
4903 pReqMsg->buckets[bktIndex].band);
4904
4905 /* Parse and fetch period */
4906 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4907 hddLog(LOGE, FL("attr period failed"));
4908 return -EINVAL;
4909 }
4910 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4911 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4912 hddLog(LOG1, FL("period %d"),
4913 pReqMsg->buckets[bktIndex].period);
4914
4915 /* Parse and fetch report events */
4916 if (!bucket[
4917 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4918 hddLog(LOGE, FL("attr report events failed"));
4919 return -EINVAL;
4920 }
4921 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4922 bucket[
4923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4924 hddLog(LOG1, FL("report events %d"),
4925 pReqMsg->buckets[bktIndex].reportEvents);
4926
4927 /* Parse and fetch max period */
4928 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4929 hddLog(LOGE, FL("attr max period failed"));
4930 return -EINVAL;
4931 }
4932 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4933 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4934 hddLog(LOG1, FL("max period %u"),
4935 pReqMsg->buckets[bktIndex].max_period);
4936
4937 /* Parse and fetch exponent */
4938 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4939 hddLog(LOGE, FL("attr exponent failed"));
4940 return -EINVAL;
4941 }
4942 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4943 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4944 hddLog(LOG1, FL("exponent %u"),
4945 pReqMsg->buckets[bktIndex].exponent);
4946
4947 /* Parse and fetch step count */
4948 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4949 hddLog(LOGE, FL("attr step count failed"));
4950 return -EINVAL;
4951 }
4952 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4953 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4954 hddLog(LOG1, FL("Step count %u"),
4955 pReqMsg->buckets[bktIndex].step_count);
4956
4957 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4959
4960 /* Framework shall pass the channel list if the input WiFi band is
4961 * WIFI_BAND_UNSPECIFIED.
4962 * If the input WiFi band is specified (any value other than
4963 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4964 */
4965 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4966 numChannels = 0;
4967 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4968 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4969 pReqMsg->buckets[bktIndex].band,
4970 chanList, &numChannels);
4971 if (!HAL_STATUS_SUCCESS(status)) {
4972 hddLog(LOGE,
4973 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4974 status);
4975 return -EINVAL;
4976 }
4977
4978 pReqMsg->buckets[bktIndex].numChannels =
4979 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4980 hddLog(LOG1, FL("Num channels %d"),
4981 pReqMsg->buckets[bktIndex].numChannels);
4982
4983 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4984 j++) {
4985 pReqMsg->buckets[bktIndex].channels[j].channel =
4986 chanList[j];
4987 pReqMsg->buckets[bktIndex].channels[j].
4988 chnlClass = 0;
4989 if (CSR_IS_CHANNEL_DFS(
4990 vos_freq_to_chan(chanList[j]))) {
4991 pReqMsg->buckets[bktIndex].channels[j].
4992 passive = 1;
4993 pReqMsg->buckets[bktIndex].channels[j].
4994 dwellTimeMs = passive_max_chn_time;
4995 } else {
4996 pReqMsg->buckets[bktIndex].channels[j].
4997 passive = 0;
4998 pReqMsg->buckets[bktIndex].channels[j].
4999 dwellTimeMs = active_max_chn_time;
5000 }
5001
5002 hddLog(LOG1,
5003 "Channel %u Passive %u Dwell time %u ms",
5004 pReqMsg->buckets[bktIndex].channels[j].channel,
5005 pReqMsg->buckets[bktIndex].channels[j].passive,
5006 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5007 }
5008
5009 bktIndex++;
5010 continue;
5011 }
5012
5013 /* Parse and fetch number of channels */
5014 if (!bucket[
5015 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5016 hddLog(LOGE, FL("attr num channels failed"));
5017 return -EINVAL;
5018 }
5019
5020 pReqMsg->buckets[bktIndex].numChannels =
5021 nla_get_u32(bucket[
5022 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5023 hddLog(LOG1, FL("num channels %d"),
5024 pReqMsg->buckets[bktIndex].numChannels);
5025
5026 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5027 hddLog(LOGE, FL("attr channel spec failed"));
5028 return -EINVAL;
5029 }
5030
5031 j = 0;
5032 nla_for_each_nested(channels,
5033 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5034 if (nla_parse(channel,
5035 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5036 nla_data(channels), nla_len(channels),
5037 wlan_hdd_extscan_config_policy)) {
5038 hddLog(LOGE, FL("nla_parse failed"));
5039 return -EINVAL;
5040 }
5041
5042 /* Parse and fetch channel */
5043 if (!channel[
5044 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5045 hddLog(LOGE, FL("attr channel failed"));
5046 return -EINVAL;
5047 }
5048 pReqMsg->buckets[bktIndex].channels[j].channel =
5049 nla_get_u32(channel[
5050 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5051 hddLog(LOG1, FL("channel %u"),
5052 pReqMsg->buckets[bktIndex].channels[j].channel);
5053
5054 /* Parse and fetch dwell time */
5055 if (!channel[
5056 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5057 hddLog(LOGE, FL("attr dwelltime failed"));
5058 return -EINVAL;
5059 }
5060 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5061 nla_get_u32(channel[
5062 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5063
5064 hddLog(LOG1, FL("Dwell time (%u ms)"),
5065 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5066
5067
5068 /* Parse and fetch channel spec passive */
5069 if (!channel[
5070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5071 hddLog(LOGE,
5072 FL("attr channel spec passive failed"));
5073 return -EINVAL;
5074 }
5075 pReqMsg->buckets[bktIndex].channels[j].passive =
5076 nla_get_u8(channel[
5077 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5078 hddLog(LOG1, FL("Chnl spec passive %u"),
5079 pReqMsg->buckets[bktIndex].channels[j].passive);
5080
5081 j++;
5082 }
5083
5084 bktIndex++;
5085 }
5086
5087 return 0;
5088}
5089
5090
5091/*
5092 * define short names for the global vendor params
5093 * used by wlan_hdd_cfg80211_extscan_start()
5094 */
5095#define PARAM_MAX \
5096QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5097#define PARAM_REQUEST_ID \
5098QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5099#define PARAM_BASE_PERIOD \
5100QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5101#define PARAM_MAX_AP_PER_SCAN \
5102QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5103#define PARAM_RPT_THRHLD_PERCENT \
5104QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5105#define PARAM_RPT_THRHLD_NUM_SCANS \
5106QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5107#define PARAM_NUM_BUCKETS \
5108QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5109
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305110static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305111 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305112 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305113{
Dino Myclee8843b32014-07-04 14:21:45 +05305114 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305115 struct net_device *dev = wdev->netdev;
5116 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5117 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5118 struct nlattr *tb[PARAM_MAX + 1];
5119 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305120 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305121 tANI_U32 request_id;
5122 struct hdd_ext_scan_context *context;
5123 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305125 ENTER();
5126
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305127 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305129
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305130 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305131 data, dataLen,
5132 wlan_hdd_extscan_config_policy)) {
5133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5134 return -EINVAL;
5135 }
5136
5137 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305138 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5140 return -EINVAL;
5141 }
5142
Dino Myclee8843b32014-07-04 14:21:45 +05305143 pReqMsg = (tpSirEXTScanStartReqParams)
5144 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5147 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305148 }
5149
5150 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305151 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305152 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5153
5154 pReqMsg->sessionId = pAdapter->sessionId;
5155 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5156
5157 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305158 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5160 goto fail;
5161 }
5162 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305163 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305164 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5165 pReqMsg->basePeriod);
5166
5167 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305168 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5170 goto fail;
5171 }
5172 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305173 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5175 pReqMsg->maxAPperScan);
5176
5177 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5180 goto fail;
5181 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305182 pReqMsg->reportThresholdPercent = nla_get_u8(
5183 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305185 pReqMsg->reportThresholdPercent);
5186
5187 /* Parse and fetch report threshold num scans */
5188 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5189 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5190 goto fail;
5191 }
5192 pReqMsg->reportThresholdNumScans = nla_get_u8(
5193 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5194 hddLog(LOG1, FL("Report Threshold num scans %d"),
5195 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196
5197 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305198 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305199 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5200 goto fail;
5201 }
5202 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305204 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5205 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5206 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5207 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5208 }
5209 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5210 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305211
Dino Mycle6fb96c12014-06-10 11:52:40 +05305212 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5214 goto fail;
5215 }
5216
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305217 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305218
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305219 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5220 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305221
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305222 context = &pHddCtx->ext_scan_context;
5223 spin_lock(&hdd_context_lock);
5224 INIT_COMPLETION(context->response_event);
5225 context->request_id = request_id = pReqMsg->requestId;
5226 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305227
Dino Mycle6fb96c12014-06-10 11:52:40 +05305228 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5229 if (!HAL_STATUS_SUCCESS(status)) {
5230 hddLog(VOS_TRACE_LEVEL_ERROR,
5231 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305232 goto fail;
5233 }
5234
Srinivas Dasari91727c12016-03-23 17:59:06 +05305235 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 /* request was sent -- wait for the response */
5238 rc = wait_for_completion_timeout(&context->response_event,
5239 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5240
5241 if (!rc) {
5242 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5243 retval = -ETIMEDOUT;
5244 } else {
5245 spin_lock(&hdd_context_lock);
5246 if (context->request_id == request_id)
5247 retval = context->response_status;
5248 else
5249 retval = -EINVAL;
5250 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305251 }
5252
Dino Myclee8843b32014-07-04 14:21:45 +05305253 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305254 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256
5257fail:
5258 vos_mem_free(pReqMsg);
5259 return -EINVAL;
5260}
5261
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305262/*
5263 * done with short names for the global vendor params
5264 * used by wlan_hdd_cfg80211_extscan_start()
5265 */
5266#undef PARAM_MAX
5267#undef PARAM_REQUEST_ID
5268#undef PARAM_BASE_PERIOD
5269#undef PARAMS_MAX_AP_PER_SCAN
5270#undef PARAMS_RPT_THRHLD_PERCENT
5271#undef PARAMS_RPT_THRHLD_NUM_SCANS
5272#undef PARAMS_NUM_BUCKETS
5273
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305274static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5275 struct wireless_dev *wdev,
5276 const void *data, int dataLen)
5277{
5278 int ret = 0;
5279
5280 vos_ssr_protect(__func__);
5281 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5282 vos_ssr_unprotect(__func__);
5283
5284 return ret;
5285}
5286
5287static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305288 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305289 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305290{
Dino Myclee8843b32014-07-04 14:21:45 +05305291 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305292 struct net_device *dev = wdev->netdev;
5293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5294 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5295 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5296 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305297 int retval;
5298 unsigned long rc;
5299 struct hdd_ext_scan_context *context;
5300 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305301
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305302 ENTER();
5303
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305304 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305305 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305306
Dino Mycle6fb96c12014-06-10 11:52:40 +05305307 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5308 data, dataLen,
5309 wlan_hdd_extscan_config_policy)) {
5310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5311 return -EINVAL;
5312 }
5313
5314 /* Parse and fetch request Id */
5315 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5317 return -EINVAL;
5318 }
5319
Dino Myclee8843b32014-07-04 14:21:45 +05305320 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305321 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305322 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305323
Dino Myclee8843b32014-07-04 14:21:45 +05305324 reqMsg.sessionId = pAdapter->sessionId;
5325 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305326
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305327 context = &pHddCtx->ext_scan_context;
5328 spin_lock(&hdd_context_lock);
5329 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305330 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305331 spin_unlock(&hdd_context_lock);
5332
Dino Myclee8843b32014-07-04 14:21:45 +05305333 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305334 if (!HAL_STATUS_SUCCESS(status)) {
5335 hddLog(VOS_TRACE_LEVEL_ERROR,
5336 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305337 return -EINVAL;
5338 }
5339
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305340 /* request was sent -- wait for the response */
5341 rc = wait_for_completion_timeout(&context->response_event,
5342 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5343
5344 if (!rc) {
5345 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5346 retval = -ETIMEDOUT;
5347 } else {
5348 spin_lock(&hdd_context_lock);
5349 if (context->request_id == request_id)
5350 retval = context->response_status;
5351 else
5352 retval = -EINVAL;
5353 spin_unlock(&hdd_context_lock);
5354 }
5355
5356 return retval;
5357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305358 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305359 return 0;
5360}
5361
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305362static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5363 struct wireless_dev *wdev,
5364 const void *data, int dataLen)
5365{
5366 int ret = 0;
5367
5368 vos_ssr_protect(__func__);
5369 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5370 vos_ssr_unprotect(__func__);
5371
5372 return ret;
5373}
5374
5375static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305376 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305377 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378{
Dino Myclee8843b32014-07-04 14:21:45 +05305379 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305380 struct net_device *dev = wdev->netdev;
5381 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5382 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5383 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5384 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305385 struct hdd_ext_scan_context *context;
5386 tANI_U32 request_id;
5387 unsigned long rc;
5388 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305389
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305390 ENTER();
5391
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305392 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305393 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305394
Dino Mycle6fb96c12014-06-10 11:52:40 +05305395 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5396 data, dataLen,
5397 wlan_hdd_extscan_config_policy)) {
5398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5399 return -EINVAL;
5400 }
5401
5402 /* Parse and fetch request Id */
5403 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5405 return -EINVAL;
5406 }
5407
Dino Myclee8843b32014-07-04 14:21:45 +05305408 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305409 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305410 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411
Dino Myclee8843b32014-07-04 14:21:45 +05305412 reqMsg.sessionId = pAdapter->sessionId;
5413 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305414
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305415 context = &pHddCtx->ext_scan_context;
5416 spin_lock(&hdd_context_lock);
5417 INIT_COMPLETION(context->response_event);
5418 context->request_id = request_id = reqMsg.requestId;
5419 spin_unlock(&hdd_context_lock);
5420
Dino Myclee8843b32014-07-04 14:21:45 +05305421 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305422 if (!HAL_STATUS_SUCCESS(status)) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR,
5424 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305425 return -EINVAL;
5426 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427
5428 /* request was sent -- wait for the response */
5429 rc = wait_for_completion_timeout(&context->response_event,
5430 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5431 if (!rc) {
5432 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5433 retval = -ETIMEDOUT;
5434 } else {
5435 spin_lock(&hdd_context_lock);
5436 if (context->request_id == request_id)
5437 retval = context->response_status;
5438 else
5439 retval = -EINVAL;
5440 spin_unlock(&hdd_context_lock);
5441 }
5442
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305443 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305444 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305445}
5446
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305447static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5448 struct wireless_dev *wdev,
5449 const void *data, int dataLen)
5450{
5451 int ret = 0;
5452
5453 vos_ssr_protect(__func__);
5454 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5455 vos_ssr_unprotect(__func__);
5456
5457 return ret;
5458}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305459#endif /* WLAN_FEATURE_EXTSCAN */
5460
Atul Mittal115287b2014-07-08 13:26:33 +05305461/*EXT TDLS*/
5462static const struct nla_policy
5463wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5464{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305465 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5466 .type = NLA_UNSPEC,
5467 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305468 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5469 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5470 {.type = NLA_S32 },
5471 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5472 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5473
5474};
5475
5476static const struct nla_policy
5477wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5478{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305479 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5480 .type = NLA_UNSPEC,
5481 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305482
5483};
5484
5485static const struct nla_policy
5486wlan_hdd_tdls_config_state_change_policy[
5487 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5488{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305489 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5490 .type = NLA_UNSPEC,
5491 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305492 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5493 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305494 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5495 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5496 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305497
5498};
5499
5500static const struct nla_policy
5501wlan_hdd_tdls_config_get_status_policy[
5502 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5503{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305504 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5505 .type = NLA_UNSPEC,
5506 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305507 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5508 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305509 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5510 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5511 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305512
5513};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305514
5515static const struct nla_policy
5516wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5519 .type = NLA_UNSPEC,
5520 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305521};
5522
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305523static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305524 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305525 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305526 int data_len)
5527{
5528
5529 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5530 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305532 ENTER();
5533
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305534 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305535 return -EINVAL;
5536 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305537 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305538 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305539 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305540 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305541 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305542 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305543 return -ENOTSUPP;
5544 }
5545
5546 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5547 data, data_len, wlan_hdd_mac_config)) {
5548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5549 return -EINVAL;
5550 }
5551
5552 /* Parse and fetch mac address */
5553 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5555 return -EINVAL;
5556 }
5557
5558 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5559 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5560 VOS_MAC_ADDR_LAST_3_BYTES);
5561
Siddharth Bhal76972212014-10-15 16:22:51 +05305562 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5563
5564 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305565 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5566 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305567 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5568 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5569 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5570 {
5571 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5572 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5573 VOS_MAC_ADDRESS_LEN);
5574 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305575 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305576
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305577 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5578 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305580 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305581 return 0;
5582}
5583
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305584static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5585 struct wireless_dev *wdev,
5586 const void *data,
5587 int data_len)
5588{
5589 int ret = 0;
5590
5591 vos_ssr_protect(__func__);
5592 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5593 vos_ssr_unprotect(__func__);
5594
5595 return ret;
5596}
5597
5598static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305599 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305600 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305601 int data_len)
5602{
5603 u8 peer[6] = {0};
5604 struct net_device *dev = wdev->netdev;
5605 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5606 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5607 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5608 eHalStatus ret;
5609 tANI_S32 state;
5610 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305611 tANI_S32 global_operating_class = 0;
5612 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305613 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305614 int retVal;
5615
5616 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305617
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305618 if (!pAdapter) {
5619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5620 return -EINVAL;
5621 }
5622
Atul Mittal115287b2014-07-08 13:26:33 +05305623 ret = wlan_hdd_validate_context(pHddCtx);
5624 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305625 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305626 return -EINVAL;
5627 }
5628 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305630 return -ENOTSUPP;
5631 }
5632 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5633 data, data_len,
5634 wlan_hdd_tdls_config_get_status_policy)) {
5635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5636 return -EINVAL;
5637 }
5638
5639 /* Parse and fetch mac address */
5640 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5642 return -EINVAL;
5643 }
5644
5645 memcpy(peer, nla_data(
5646 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5647 sizeof(peer));
5648 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5649
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305650 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305651
Atul Mittal115287b2014-07-08 13:26:33 +05305652 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305653 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305654 NLMSG_HDRLEN);
5655
5656 if (!skb) {
5657 hddLog(VOS_TRACE_LEVEL_ERROR,
5658 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5659 return -EINVAL;
5660 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305662 reason,
5663 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 global_operating_class,
5665 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305666 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305667 if (nla_put_s32(skb,
5668 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5669 state) ||
5670 nla_put_s32(skb,
5671 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5672 reason) ||
5673 nla_put_s32(skb,
5674 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5675 global_operating_class) ||
5676 nla_put_s32(skb,
5677 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5678 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305679
5680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5681 goto nla_put_failure;
5682 }
5683
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305684 retVal = cfg80211_vendor_cmd_reply(skb);
5685 EXIT();
5686 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305687
5688nla_put_failure:
5689 kfree_skb(skb);
5690 return -EINVAL;
5691}
5692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305693static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5694 struct wireless_dev *wdev,
5695 const void *data,
5696 int data_len)
5697{
5698 int ret = 0;
5699
5700 vos_ssr_protect(__func__);
5701 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5702 vos_ssr_unprotect(__func__);
5703
5704 return ret;
5705}
5706
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305707static int wlan_hdd_cfg80211_exttdls_callback(
5708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5709 const tANI_U8* mac,
5710#else
5711 tANI_U8* mac,
5712#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305713 tANI_S32 state,
5714 tANI_S32 reason,
5715 void *ctx)
5716{
5717 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305718 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305719 tANI_S32 global_operating_class = 0;
5720 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305721 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305722
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305723 ENTER();
5724
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305725 if (!pAdapter) {
5726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5727 return -EINVAL;
5728 }
5729
5730 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305731 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305733 return -EINVAL;
5734 }
5735
5736 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305738 return -ENOTSUPP;
5739 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305740 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5742 NULL,
5743#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305744 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5745 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5746 GFP_KERNEL);
5747
5748 if (!skb) {
5749 hddLog(VOS_TRACE_LEVEL_ERROR,
5750 FL("cfg80211_vendor_event_alloc failed"));
5751 return -EINVAL;
5752 }
5753 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305754 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5755 reason,
5756 state,
5757 global_operating_class,
5758 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305759 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5760 MAC_ADDR_ARRAY(mac));
5761
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305762 if (nla_put(skb,
5763 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5764 VOS_MAC_ADDR_SIZE, mac) ||
5765 nla_put_s32(skb,
5766 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5767 state) ||
5768 nla_put_s32(skb,
5769 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5770 reason) ||
5771 nla_put_s32(skb,
5772 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5773 channel) ||
5774 nla_put_s32(skb,
5775 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5776 global_operating_class)
5777 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5779 goto nla_put_failure;
5780 }
5781
5782 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305783 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305784 return (0);
5785
5786nla_put_failure:
5787 kfree_skb(skb);
5788 return -EINVAL;
5789}
5790
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305791static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305792 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305793 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305794 int data_len)
5795{
5796 u8 peer[6] = {0};
5797 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305798 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5799 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5800 eHalStatus status;
5801 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305802 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305803 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305804
5805 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305806
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305807 if (!dev) {
5808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5809 return -EINVAL;
5810 }
5811
5812 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5813 if (!pAdapter) {
5814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5815 return -EINVAL;
5816 }
5817
Atul Mittal115287b2014-07-08 13:26:33 +05305818 status = wlan_hdd_validate_context(pHddCtx);
5819 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305821 return -EINVAL;
5822 }
5823 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305825 return -ENOTSUPP;
5826 }
5827 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5828 data, data_len,
5829 wlan_hdd_tdls_config_enable_policy)) {
5830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5831 return -EINVAL;
5832 }
5833
5834 /* Parse and fetch mac address */
5835 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5836 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5837 return -EINVAL;
5838 }
5839
5840 memcpy(peer, nla_data(
5841 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5842 sizeof(peer));
5843 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5844
5845 /* Parse and fetch channel */
5846 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5848 return -EINVAL;
5849 }
5850 pReqMsg.channel = nla_get_s32(
5851 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5852 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5853
5854 /* Parse and fetch global operating class */
5855 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5857 return -EINVAL;
5858 }
5859 pReqMsg.global_operating_class = nla_get_s32(
5860 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5861 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5862 pReqMsg.global_operating_class);
5863
5864 /* Parse and fetch latency ms */
5865 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5867 return -EINVAL;
5868 }
5869 pReqMsg.max_latency_ms = nla_get_s32(
5870 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5872 pReqMsg.max_latency_ms);
5873
5874 /* Parse and fetch required bandwidth kbps */
5875 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5877 return -EINVAL;
5878 }
5879
5880 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5881 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5882 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5883 pReqMsg.min_bandwidth_kbps);
5884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305885 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305886 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305887 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305888 wlan_hdd_cfg80211_exttdls_callback);
5889
5890 EXIT();
5891 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305892}
5893
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305894static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5895 struct wireless_dev *wdev,
5896 const void *data,
5897 int data_len)
5898{
5899 int ret = 0;
5900
5901 vos_ssr_protect(__func__);
5902 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5903 vos_ssr_unprotect(__func__);
5904
5905 return ret;
5906}
5907
5908static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305909 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305910 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305911 int data_len)
5912{
5913 u8 peer[6] = {0};
5914 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5916 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5917 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305918 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305919 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305920
5921 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305922
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305923 if (!dev) {
5924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5925 return -EINVAL;
5926 }
5927
5928 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5929 if (!pAdapter) {
5930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5931 return -EINVAL;
5932 }
5933
Atul Mittal115287b2014-07-08 13:26:33 +05305934 status = wlan_hdd_validate_context(pHddCtx);
5935 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305937 return -EINVAL;
5938 }
5939 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305941 return -ENOTSUPP;
5942 }
5943 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5944 data, data_len,
5945 wlan_hdd_tdls_config_disable_policy)) {
5946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5947 return -EINVAL;
5948 }
5949 /* Parse and fetch mac address */
5950 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5952 return -EINVAL;
5953 }
5954
5955 memcpy(peer, nla_data(
5956 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5957 sizeof(peer));
5958 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305960 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5961
5962 EXIT();
5963 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305964}
5965
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305966static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5967 struct wireless_dev *wdev,
5968 const void *data,
5969 int data_len)
5970{
5971 int ret = 0;
5972
5973 vos_ssr_protect(__func__);
5974 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5975 vos_ssr_unprotect(__func__);
5976
5977 return ret;
5978}
5979
Dasari Srinivas7875a302014-09-26 17:50:57 +05305980static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305981__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305982 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305983 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305984{
5985 struct net_device *dev = wdev->netdev;
5986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5987 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5988 struct sk_buff *skb = NULL;
5989 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305990 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305991
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305992 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305993
5994 ret = wlan_hdd_validate_context(pHddCtx);
5995 if (0 != ret)
5996 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305997 return ret;
5998 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305999 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6000 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6001 fset |= WIFI_FEATURE_INFRA;
6002 }
6003
6004 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6005 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6006 fset |= WIFI_FEATURE_INFRA_5G;
6007 }
6008
6009#ifdef WLAN_FEATURE_P2P
6010 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6011 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6012 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6013 fset |= WIFI_FEATURE_P2P;
6014 }
6015#endif
6016
6017 /* Soft-AP is supported currently by default */
6018 fset |= WIFI_FEATURE_SOFT_AP;
6019
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306020 /* HOTSPOT is a supplicant feature, enable it by default */
6021 fset |= WIFI_FEATURE_HOTSPOT;
6022
Dasari Srinivas7875a302014-09-26 17:50:57 +05306023#ifdef WLAN_FEATURE_EXTSCAN
6024 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306025 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6026 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6027 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306028 fset |= WIFI_FEATURE_EXTSCAN;
6029 }
6030#endif
6031
Dasari Srinivas7875a302014-09-26 17:50:57 +05306032 if (sme_IsFeatureSupportedByFW(NAN)) {
6033 hddLog(LOG1, FL("NAN is supported by firmware"));
6034 fset |= WIFI_FEATURE_NAN;
6035 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306036
6037 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306038 if (sme_IsFeatureSupportedByFW(RTT) &&
6039 pHddCtx->cfg_ini->enable_rtt_support) {
6040 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306041 fset |= WIFI_FEATURE_D2AP_RTT;
6042 }
6043
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306044 if (sme_IsFeatureSupportedByFW(RTT3)) {
6045 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6046 fset |= WIFI_FEATURE_RTT3;
6047 }
6048
Dasari Srinivas7875a302014-09-26 17:50:57 +05306049#ifdef FEATURE_WLAN_BATCH_SCAN
6050 if (fset & WIFI_FEATURE_EXTSCAN) {
6051 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6052 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6053 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6054 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6055 fset |= WIFI_FEATURE_BATCH_SCAN;
6056 }
6057#endif
6058
6059#ifdef FEATURE_WLAN_SCAN_PNO
6060 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6061 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6062 hddLog(LOG1, FL("PNO is supported by firmware"));
6063 fset |= WIFI_FEATURE_PNO;
6064 }
6065#endif
6066
6067 /* STA+STA is supported currently by default */
6068 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6069
6070#ifdef FEATURE_WLAN_TDLS
6071 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6072 sme_IsFeatureSupportedByFW(TDLS)) {
6073 hddLog(LOG1, FL("TDLS is supported by firmware"));
6074 fset |= WIFI_FEATURE_TDLS;
6075 }
6076
6077 /* TDLS_OFFCHANNEL is not supported currently by default */
6078#endif
6079
6080#ifdef WLAN_AP_STA_CONCURRENCY
6081 /* AP+STA concurrency is supported currently by default */
6082 fset |= WIFI_FEATURE_AP_STA;
6083#endif
6084
Mukul Sharma5add0532015-08-17 15:57:47 +05306085#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306086 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6087 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306088 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6089 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306090 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306091#endif
6092
Dasari Srinivas7875a302014-09-26 17:50:57 +05306093 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6094 NLMSG_HDRLEN);
6095
6096 if (!skb) {
6097 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6098 return -EINVAL;
6099 }
6100 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6101
6102 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6103 hddLog(LOGE, FL("nla put fail"));
6104 goto nla_put_failure;
6105 }
6106
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306107 ret = cfg80211_vendor_cmd_reply(skb);
6108 EXIT();
6109 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306110
6111nla_put_failure:
6112 kfree_skb(skb);
6113 return -EINVAL;
6114}
6115
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306116static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306117wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6118 struct wireless_dev *wdev,
6119 const void *data, int data_len)
6120{
6121 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306122 vos_ssr_protect(__func__);
6123 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6124 vos_ssr_unprotect(__func__);
6125
6126 return ret;
6127}
6128
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306129
6130static const struct
6131nla_policy
6132qca_wlan_vendor_wifi_logger_get_ring_data_policy
6133[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6134 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6135 = {.type = NLA_U32 },
6136};
6137
6138static int
6139 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6140 struct wireless_dev *wdev,
6141 const void *data,
6142 int data_len)
6143{
6144 int ret;
6145 VOS_STATUS status;
6146 uint32_t ring_id;
6147 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6148 struct nlattr *tb
6149 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6150
6151 ENTER();
6152
6153 ret = wlan_hdd_validate_context(hdd_ctx);
6154 if (0 != ret) {
6155 return ret;
6156 }
6157
6158 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6159 data, data_len,
6160 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6161 hddLog(LOGE, FL("Invalid attribute"));
6162 return -EINVAL;
6163 }
6164
6165 /* Parse and fetch ring id */
6166 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6167 hddLog(LOGE, FL("attr ATTR failed"));
6168 return -EINVAL;
6169 }
6170
6171 ring_id = nla_get_u32(
6172 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6173
6174 hddLog(LOG1, FL("Bug report triggered by framework"));
6175
6176 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6177 WLAN_LOG_INDICATOR_FRAMEWORK,
6178 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306179 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306180 );
6181 if (VOS_STATUS_SUCCESS != status) {
6182 hddLog(LOGE, FL("Failed to trigger bug report"));
6183
6184 return -EINVAL;
6185 }
6186
6187 return 0;
6188
6189
6190}
6191
6192
6193static int
6194 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6195 struct wireless_dev *wdev,
6196 const void *data,
6197 int data_len)
6198{
6199 int ret = 0;
6200
6201 vos_ssr_protect(__func__);
6202 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6203 wdev, data, data_len);
6204 vos_ssr_unprotect(__func__);
6205
6206 return ret;
6207
6208}
6209
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306210#define MAX_CONCURRENT_MATRIX \
6211 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6212#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6213 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6214static const struct nla_policy
6215wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6216 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6217};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306218
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306219static int
6220__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306221 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306222 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306223{
6224 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6225 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306226 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306227 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306228 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6229 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306230
6231 ENTER();
6232
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306233 ret = wlan_hdd_validate_context(pHddCtx);
6234 if (0 != ret)
6235 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306236 return ret;
6237 }
6238
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306239 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6240 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306241 hddLog(LOGE, FL("Invalid ATTR"));
6242 return -EINVAL;
6243 }
6244
6245 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306246 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306247 hddLog(LOGE, FL("Attr max feature set size failed"));
6248 return -EINVAL;
6249 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306250 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306251 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6252
6253 /* Fill feature combination matrix */
6254 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306255 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6256 WIFI_FEATURE_P2P;
6257
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306258 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6259 WIFI_FEATURE_SOFT_AP;
6260
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306261 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6262 WIFI_FEATURE_SOFT_AP;
6263
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306264 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6265 WIFI_FEATURE_SOFT_AP |
6266 WIFI_FEATURE_P2P;
6267
6268 /* Add more feature combinations here */
6269
6270 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6271 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6272 hddLog(LOG1, "Feature set matrix");
6273 for (i = 0; i < feature_sets; i++)
6274 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6275
6276 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6277 sizeof(u32) * feature_sets +
6278 NLMSG_HDRLEN);
6279
6280 if (reply_skb) {
6281 if (nla_put_u32(reply_skb,
6282 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6283 feature_sets) ||
6284 nla_put(reply_skb,
6285 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6286 sizeof(u32) * feature_sets, feature_set_matrix)) {
6287 hddLog(LOGE, FL("nla put fail"));
6288 kfree_skb(reply_skb);
6289 return -EINVAL;
6290 }
6291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306292 ret = cfg80211_vendor_cmd_reply(reply_skb);
6293 EXIT();
6294 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306295 }
6296 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6297 return -ENOMEM;
6298
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306299}
6300
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306301#undef MAX_CONCURRENT_MATRIX
6302#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6303
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306304static int
6305wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6306 struct wireless_dev *wdev,
6307 const void *data, int data_len)
6308{
6309 int ret = 0;
6310
6311 vos_ssr_protect(__func__);
6312 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6313 data_len);
6314 vos_ssr_unprotect(__func__);
6315
6316 return ret;
6317}
6318
c_manjeecfd1efb2015-09-25 19:32:34 +05306319
6320static int
6321__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6322 struct wireless_dev *wdev,
6323 const void *data, int data_len)
6324{
6325 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6326 int ret;
6327 ENTER();
6328
6329 ret = wlan_hdd_validate_context(pHddCtx);
6330 if (0 != ret)
6331 {
6332 return ret;
6333 }
6334
6335 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6336 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6337 {
6338 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306339 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306340 }
6341 /*call common API for FW mem dump req*/
6342 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6343
Abhishek Singhc783fa72015-12-09 18:07:34 +05306344 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306345 {
6346 /*indicate to userspace the status of fw mem dump */
6347 wlan_indicate_mem_dump_complete(true);
6348 }
6349 else
6350 {
6351 /*else send failure to userspace */
6352 wlan_indicate_mem_dump_complete(false);
6353 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306354 EXIT();
6355 return ret;
6356}
6357
6358/**
6359 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6360 * @wiphy: pointer to wireless wiphy structure.
6361 * @wdev: pointer to wireless_dev structure.
6362 * @data: Pointer to the NL data.
6363 * @data_len:Length of @data
6364 *
6365 * This is called when wlan driver needs to get the firmware memory dump
6366 * via vendor specific command.
6367 *
6368 * Return: 0 on success, error number otherwise.
6369 */
6370
6371static int
6372wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6373 struct wireless_dev *wdev,
6374 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306375{
6376 int ret = 0;
6377 vos_ssr_protect(__func__);
6378 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6379 data_len);
6380 vos_ssr_unprotect(__func__);
6381 return ret;
6382}
c_manjeecfd1efb2015-09-25 19:32:34 +05306383
Sushant Kaushik8e644982015-09-23 12:18:54 +05306384static const struct
6385nla_policy
6386qca_wlan_vendor_wifi_logger_start_policy
6387[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6388 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6389 = {.type = NLA_U32 },
6390 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6391 = {.type = NLA_U32 },
6392 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6393 = {.type = NLA_U32 },
6394};
6395
6396/**
6397 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6398 * or disable the collection of packet statistics from the firmware
6399 * @wiphy: WIPHY structure pointer
6400 * @wdev: Wireless device structure pointer
6401 * @data: Pointer to the data received
6402 * @data_len: Length of the data received
6403 *
6404 * This function is used to enable or disable the collection of packet
6405 * statistics from the firmware
6406 *
6407 * Return: 0 on success and errno on failure
6408 */
6409static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6410 struct wireless_dev *wdev,
6411 const void *data,
6412 int data_len)
6413{
6414 eHalStatus status;
6415 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6416 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6417 tAniWifiStartLog start_log;
6418
6419 status = wlan_hdd_validate_context(hdd_ctx);
6420 if (0 != status) {
6421 return -EINVAL;
6422 }
6423
6424 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6425 data, data_len,
6426 qca_wlan_vendor_wifi_logger_start_policy)) {
6427 hddLog(LOGE, FL("Invalid attribute"));
6428 return -EINVAL;
6429 }
6430
6431 /* Parse and fetch ring id */
6432 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6433 hddLog(LOGE, FL("attr ATTR failed"));
6434 return -EINVAL;
6435 }
6436 start_log.ringId = nla_get_u32(
6437 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6438 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6439
6440 /* Parse and fetch verbose level */
6441 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6442 hddLog(LOGE, FL("attr verbose_level failed"));
6443 return -EINVAL;
6444 }
6445 start_log.verboseLevel = nla_get_u32(
6446 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6447 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6448
6449 /* Parse and fetch flag */
6450 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6451 hddLog(LOGE, FL("attr flag failed"));
6452 return -EINVAL;
6453 }
6454 start_log.flag = nla_get_u32(
6455 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6456 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6457
6458 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306459 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6460 !vos_isPktStatsEnabled()))
6461
Sushant Kaushik8e644982015-09-23 12:18:54 +05306462 {
6463 hddLog(LOGE, FL("per pkt stats not enabled"));
6464 return -EINVAL;
6465 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306466
Sushant Kaushik33200572015-08-05 16:46:20 +05306467 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306468 return 0;
6469}
6470
6471/**
6472 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6473 * or disable the collection of packet statistics from the firmware
6474 * @wiphy: WIPHY structure pointer
6475 * @wdev: Wireless device structure pointer
6476 * @data: Pointer to the data received
6477 * @data_len: Length of the data received
6478 *
6479 * This function is used to enable or disable the collection of packet
6480 * statistics from the firmware
6481 *
6482 * Return: 0 on success and errno on failure
6483 */
6484static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6485 struct wireless_dev *wdev,
6486 const void *data,
6487 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306488{
6489 int ret = 0;
6490
6491 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306492
6493 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6494 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306495 vos_ssr_unprotect(__func__);
6496
6497 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306498}
6499
6500
Agarwal Ashish738843c2014-09-25 12:27:56 +05306501static const struct nla_policy
6502wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6503 +1] =
6504{
6505 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6506};
6507
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306508static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306509 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306510 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306511 int data_len)
6512{
6513 struct net_device *dev = wdev->netdev;
6514 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6515 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6516 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6517 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6518 eHalStatus status;
6519 u32 dfsFlag = 0;
6520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306521 ENTER();
6522
Agarwal Ashish738843c2014-09-25 12:27:56 +05306523 status = wlan_hdd_validate_context(pHddCtx);
6524 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306525 return -EINVAL;
6526 }
6527 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6528 data, data_len,
6529 wlan_hdd_set_no_dfs_flag_config_policy)) {
6530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6531 return -EINVAL;
6532 }
6533
6534 /* Parse and fetch required bandwidth kbps */
6535 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6537 return -EINVAL;
6538 }
6539
6540 dfsFlag = nla_get_u32(
6541 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6542 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6543 dfsFlag);
6544
6545 pHddCtx->disable_dfs_flag = dfsFlag;
6546
6547 sme_disable_dfs_channel(hHal, dfsFlag);
6548 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306549
6550 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306551 return 0;
6552}
Atul Mittal115287b2014-07-08 13:26:33 +05306553
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306554static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6555 struct wireless_dev *wdev,
6556 const void *data,
6557 int data_len)
6558{
6559 int ret = 0;
6560
6561 vos_ssr_protect(__func__);
6562 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6563 vos_ssr_unprotect(__func__);
6564
6565 return ret;
6566
6567}
6568
Mukul Sharma2a271632014-10-13 14:59:01 +05306569const struct
6570nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6571{
6572 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306573 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6574 .type = NLA_UNSPEC,
6575 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306576};
6577
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306578static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306579 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306580{
6581
6582 u8 bssid[6] = {0};
6583 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6584 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6585 eHalStatus status = eHAL_STATUS_SUCCESS;
6586 v_U32_t isFwrRoamEnabled = FALSE;
6587 int ret;
6588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306589 ENTER();
6590
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306591 ret = wlan_hdd_validate_context(pHddCtx);
6592 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306593 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306594 }
6595
6596 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6597 data, data_len,
6598 qca_wlan_vendor_attr);
6599 if (ret){
6600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6601 return -EINVAL;
6602 }
6603
6604 /* Parse and fetch Enable flag */
6605 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6607 return -EINVAL;
6608 }
6609
6610 isFwrRoamEnabled = nla_get_u32(
6611 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6612
6613 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6614
6615 /* Parse and fetch bssid */
6616 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6618 return -EINVAL;
6619 }
6620
6621 memcpy(bssid, nla_data(
6622 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6623 sizeof(bssid));
6624 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6625
6626 //Update roaming
6627 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306628 if (!HAL_STATUS_SUCCESS(status)) {
6629 hddLog(LOGE,
6630 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6631 return -EINVAL;
6632 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306633 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306634 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306635}
6636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306637static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6638 struct wireless_dev *wdev, const void *data, int data_len)
6639{
6640 int ret = 0;
6641
6642 vos_ssr_protect(__func__);
6643 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6644 vos_ssr_unprotect(__func__);
6645
6646 return ret;
6647}
6648
Sushant Kaushik847890c2015-09-28 16:05:17 +05306649static const struct
6650nla_policy
6651qca_wlan_vendor_get_wifi_info_policy[
6652 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6653 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6654 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6655};
6656
6657
6658/**
6659 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6660 * @wiphy: pointer to wireless wiphy structure.
6661 * @wdev: pointer to wireless_dev structure.
6662 * @data: Pointer to the data to be passed via vendor interface
6663 * @data_len:Length of the data to be passed
6664 *
6665 * This is called when wlan driver needs to send wifi driver related info
6666 * (driver/fw version) to the user space application upon request.
6667 *
6668 * Return: Return the Success or Failure code.
6669 */
6670static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6671 struct wireless_dev *wdev,
6672 const void *data, int data_len)
6673{
6674 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6675 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6676 tSirVersionString version;
6677 uint32 version_len;
6678 uint8 attr;
6679 int status;
6680 struct sk_buff *reply_skb = NULL;
6681
6682 if (VOS_FTM_MODE == hdd_get_conparam()) {
6683 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6684 return -EINVAL;
6685 }
6686
6687 status = wlan_hdd_validate_context(hdd_ctx);
6688 if (0 != status) {
6689 hddLog(LOGE, FL("HDD context is not valid"));
6690 return -EINVAL;
6691 }
6692
6693 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6694 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6695 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6696 return -EINVAL;
6697 }
6698
6699 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6700 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6701 QWLAN_VERSIONSTR);
6702 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6703 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6704 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6705 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6706 hdd_ctx->fw_Version);
6707 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6708 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6709 } else {
6710 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6711 return -EINVAL;
6712 }
6713
6714 version_len = strlen(version);
6715 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6716 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6717 if (!reply_skb) {
6718 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6719 return -ENOMEM;
6720 }
6721
6722 if (nla_put(reply_skb, attr, version_len, version)) {
6723 hddLog(LOGE, FL("nla put fail"));
6724 kfree_skb(reply_skb);
6725 return -EINVAL;
6726 }
6727
6728 return cfg80211_vendor_cmd_reply(reply_skb);
6729}
6730
6731/**
6732 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6733 * @wiphy: pointer to wireless wiphy structure.
6734 * @wdev: pointer to wireless_dev structure.
6735 * @data: Pointer to the data to be passed via vendor interface
6736 * @data_len:Length of the data to be passed
6737 * @data_len: Length of the data received
6738 *
6739 * This function is used to enable or disable the collection of packet
6740 * statistics from the firmware
6741 *
6742 * Return: 0 on success and errno on failure
6743 */
6744
6745static int
6746wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6747 struct wireless_dev *wdev,
6748 const void *data, int data_len)
6749
6750
6751{
6752 int ret = 0;
6753
6754 vos_ssr_protect(__func__);
6755 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6756 wdev, data, data_len);
6757 vos_ssr_unprotect(__func__);
6758
6759 return ret;
6760}
6761
6762
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306763/*
6764 * define short names for the global vendor params
6765 * used by __wlan_hdd_cfg80211_monitor_rssi()
6766 */
6767#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6768#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6769#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6770#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6771#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6772
6773/**---------------------------------------------------------------------------
6774
6775 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6776 monitor start is completed successfully.
6777
6778 \return - None
6779
6780 --------------------------------------------------------------------------*/
6781void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6782{
6783 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6784
6785 if (NULL == pHddCtx)
6786 {
6787 hddLog(VOS_TRACE_LEVEL_ERROR,
6788 "%s: HDD context is NULL",__func__);
6789 return;
6790 }
6791
6792 if (VOS_STATUS_SUCCESS == status)
6793 {
6794 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6795 }
6796 else
6797 {
6798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6799 }
6800
6801 return;
6802}
6803
6804/**---------------------------------------------------------------------------
6805
6806 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6807 stop is completed successfully.
6808
6809 \return - None
6810
6811 --------------------------------------------------------------------------*/
6812void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6813{
6814 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6815
6816 if (NULL == pHddCtx)
6817 {
6818 hddLog(VOS_TRACE_LEVEL_ERROR,
6819 "%s: HDD context is NULL",__func__);
6820 return;
6821 }
6822
6823 if (VOS_STATUS_SUCCESS == status)
6824 {
6825 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6826 }
6827 else
6828 {
6829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6830 }
6831
6832 return;
6833}
6834
6835/**
6836 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6837 * @wiphy: Pointer to wireless phy
6838 * @wdev: Pointer to wireless device
6839 * @data: Pointer to data
6840 * @data_len: Data length
6841 *
6842 * Return: 0 on success, negative errno on failure
6843 */
6844
6845static int
6846__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6847 struct wireless_dev *wdev,
6848 const void *data,
6849 int data_len)
6850{
6851 struct net_device *dev = wdev->netdev;
6852 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6853 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6854 hdd_station_ctx_t *pHddStaCtx;
6855 struct nlattr *tb[PARAM_MAX + 1];
6856 tpSirRssiMonitorReq pReq;
6857 eHalStatus status;
6858 int ret;
6859 uint32_t control;
6860 static const struct nla_policy policy[PARAM_MAX + 1] = {
6861 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6862 [PARAM_CONTROL] = { .type = NLA_U32 },
6863 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6864 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6865 };
6866
6867 ENTER();
6868
6869 ret = wlan_hdd_validate_context(hdd_ctx);
6870 if (0 != ret) {
6871 return -EINVAL;
6872 }
6873
6874 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6875 hddLog(LOGE, FL("Not in Connected state!"));
6876 return -ENOTSUPP;
6877 }
6878
6879 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6880 hddLog(LOGE, FL("Invalid ATTR"));
6881 return -EINVAL;
6882 }
6883
6884 if (!tb[PARAM_REQUEST_ID]) {
6885 hddLog(LOGE, FL("attr request id failed"));
6886 return -EINVAL;
6887 }
6888
6889 if (!tb[PARAM_CONTROL]) {
6890 hddLog(LOGE, FL("attr control failed"));
6891 return -EINVAL;
6892 }
6893
6894 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6895
6896 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6897 if(NULL == pReq)
6898 {
6899 hddLog(LOGE,
6900 FL("vos_mem_alloc failed "));
6901 return eHAL_STATUS_FAILED_ALLOC;
6902 }
6903 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6904
6905 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6906 pReq->sessionId = pAdapter->sessionId;
6907 pReq->rssiMonitorCbContext = hdd_ctx;
6908 control = nla_get_u32(tb[PARAM_CONTROL]);
6909 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6910
6911 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6912 pReq->requestId, pReq->sessionId, control);
6913
6914 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6915 if (!tb[PARAM_MIN_RSSI]) {
6916 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306917 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306918 }
6919
6920 if (!tb[PARAM_MAX_RSSI]) {
6921 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306922 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306923 }
6924
6925 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6926 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6927 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6928
6929 if (!(pReq->minRssi < pReq->maxRssi)) {
6930 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6931 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306932 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306933 }
6934 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6935 pReq->minRssi, pReq->maxRssi);
6936 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6937
6938 }
6939 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6940 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6941 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6942 }
6943 else {
6944 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306945 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306946 }
6947
6948 if (!HAL_STATUS_SUCCESS(status)) {
6949 hddLog(LOGE,
6950 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306951 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306952 }
6953
6954 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306955fail:
6956 vos_mem_free(pReq);
6957 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306958}
6959
6960/*
6961 * done with short names for the global vendor params
6962 * used by __wlan_hdd_cfg80211_monitor_rssi()
6963 */
6964#undef PARAM_MAX
6965#undef PARAM_CONTROL
6966#undef PARAM_REQUEST_ID
6967#undef PARAM_MAX_RSSI
6968#undef PARAM_MIN_RSSI
6969
6970/**
6971 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6972 * @wiphy: wiphy structure pointer
6973 * @wdev: Wireless device structure pointer
6974 * @data: Pointer to the data received
6975 * @data_len: Length of @data
6976 *
6977 * Return: 0 on success; errno on failure
6978 */
6979static int
6980wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6981 const void *data, int data_len)
6982{
6983 int ret;
6984
6985 vos_ssr_protect(__func__);
6986 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6987 vos_ssr_unprotect(__func__);
6988
6989 return ret;
6990}
6991
6992/**
6993 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6994 * @hddctx: HDD context
6995 * @data: rssi breached event data
6996 *
6997 * This function reads the rssi breached event %data and fill in the skb with
6998 * NL attributes and send up the NL event.
6999 * This callback execute in atomic context and must not invoke any
7000 * blocking calls.
7001 *
7002 * Return: none
7003 */
7004void hdd_rssi_threshold_breached_cb(void *hddctx,
7005 struct rssi_breach_event *data)
7006{
7007 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7008 int status;
7009 struct sk_buff *skb;
7010
7011 ENTER();
7012 status = wlan_hdd_validate_context(pHddCtx);
7013
7014 if (0 != status) {
7015 return;
7016 }
7017
7018 if (!data) {
7019 hddLog(LOGE, FL("data is null"));
7020 return;
7021 }
7022
7023 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7025 NULL,
7026#endif
7027 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7028 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7029 GFP_KERNEL);
7030
7031 if (!skb) {
7032 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7033 return;
7034 }
7035
7036 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7037 data->request_id, data->curr_rssi);
7038 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7039 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7040
7041 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7042 data->request_id) ||
7043 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7044 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7045 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7046 data->curr_rssi)) {
7047 hddLog(LOGE, FL("nla put fail"));
7048 goto fail;
7049 }
7050
7051 cfg80211_vendor_event(skb, GFP_KERNEL);
7052 return;
7053
7054fail:
7055 kfree_skb(skb);
7056 return;
7057}
7058
7059
7060
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307061/**
7062 * __wlan_hdd_cfg80211_setband() - set band
7063 * @wiphy: Pointer to wireless phy
7064 * @wdev: Pointer to wireless device
7065 * @data: Pointer to data
7066 * @data_len: Data length
7067 *
7068 * Return: 0 on success, negative errno on failure
7069 */
7070static int
7071__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7072 struct wireless_dev *wdev,
7073 const void *data,
7074 int data_len)
7075{
7076 struct net_device *dev = wdev->netdev;
7077 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7078 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7079 int ret;
7080 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7081 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7082
7083 ENTER();
7084
7085 ret = wlan_hdd_validate_context(hdd_ctx);
7086 if (0 != ret) {
7087 hddLog(LOGE, FL("HDD context is not valid"));
7088 return ret;
7089 }
7090
7091 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7092 policy)) {
7093 hddLog(LOGE, FL("Invalid ATTR"));
7094 return -EINVAL;
7095 }
7096
7097 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7098 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7099 return -EINVAL;
7100 }
7101
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307102 hdd_ctx->isSetBandByNL = TRUE;
7103 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307104 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307105 hdd_ctx->isSetBandByNL = FALSE;
7106
7107 EXIT();
7108 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307109}
7110
7111/**
7112 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7113 * @wiphy: wiphy structure pointer
7114 * @wdev: Wireless device structure pointer
7115 * @data: Pointer to the data received
7116 * @data_len: Length of @data
7117 *
7118 * Return: 0 on success; errno on failure
7119 */
7120static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7121 struct wireless_dev *wdev,
7122 const void *data,
7123 int data_len)
7124{
7125 int ret = 0;
7126
7127 vos_ssr_protect(__func__);
7128 ret = __wlan_hdd_cfg80211_setband(wiphy,
7129 wdev, data, data_len);
7130 vos_ssr_unprotect(__func__);
7131
7132 return ret;
7133}
7134
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307135#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7136/**
7137 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7138 * @hdd_ctx: HDD context
7139 * @request_id: [input] request id
7140 * @pattern_id: [output] pattern id
7141 *
7142 * This function loops through request id to pattern id array
7143 * if the slot is available, store the request id and return pattern id
7144 * if entry exists, return the pattern id
7145 *
7146 * Return: 0 on success and errno on failure
7147 */
7148static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7149 uint32_t request_id,
7150 uint8_t *pattern_id)
7151{
7152 uint32_t i;
7153
7154 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7155 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7156 {
7157 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7158 {
7159 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7160 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7161 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7162 return 0;
7163 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7164 request_id) {
7165 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7166 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7167 return 0;
7168 }
7169 }
7170 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7171 return -EINVAL;
7172}
7173
7174/**
7175 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7176 * @hdd_ctx: HDD context
7177 * @request_id: [input] request id
7178 * @pattern_id: [output] pattern id
7179 *
7180 * This function loops through request id to pattern id array
7181 * reset request id to 0 (slot available again) and
7182 * return pattern id
7183 *
7184 * Return: 0 on success and errno on failure
7185 */
7186static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7187 uint32_t request_id,
7188 uint8_t *pattern_id)
7189{
7190 uint32_t i;
7191
7192 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7193 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7194 {
7195 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7196 {
7197 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7198 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7199 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7200 return 0;
7201 }
7202 }
7203 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7204 return -EINVAL;
7205}
7206
7207
7208/*
7209 * define short names for the global vendor params
7210 * used by __wlan_hdd_cfg80211_offloaded_packets()
7211 */
7212#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7213#define PARAM_REQUEST_ID \
7214 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7215#define PARAM_CONTROL \
7216 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7217#define PARAM_IP_PACKET \
7218 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7219#define PARAM_SRC_MAC_ADDR \
7220 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7221#define PARAM_DST_MAC_ADDR \
7222 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7223#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7224
7225/**
7226 * wlan_hdd_add_tx_ptrn() - add tx pattern
7227 * @adapter: adapter pointer
7228 * @hdd_ctx: hdd context
7229 * @tb: nl attributes
7230 *
7231 * This function reads the NL attributes and forms a AddTxPtrn message
7232 * posts it to SME.
7233 *
7234 */
7235static int
7236wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7237 struct nlattr **tb)
7238{
7239 struct sSirAddPeriodicTxPtrn *add_req;
7240 eHalStatus status;
7241 uint32_t request_id, ret, len;
7242 uint8_t pattern_id = 0;
7243 v_MACADDR_t dst_addr;
7244 uint16_t eth_type = htons(ETH_P_IP);
7245
7246 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7247 {
7248 hddLog(LOGE, FL("Not in Connected state!"));
7249 return -ENOTSUPP;
7250 }
7251
7252 add_req = vos_mem_malloc(sizeof(*add_req));
7253 if (!add_req)
7254 {
7255 hddLog(LOGE, FL("memory allocation failed"));
7256 return -ENOMEM;
7257 }
7258
7259 /* Parse and fetch request Id */
7260 if (!tb[PARAM_REQUEST_ID])
7261 {
7262 hddLog(LOGE, FL("attr request id failed"));
7263 goto fail;
7264 }
7265
7266 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7267 hddLog(LOG1, FL("Request Id: %u"), request_id);
7268 if (request_id == 0)
7269 {
7270 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307271 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307272 }
7273
7274 if (!tb[PARAM_PERIOD])
7275 {
7276 hddLog(LOGE, FL("attr period failed"));
7277 goto fail;
7278 }
7279 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7280 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7281 if (add_req->usPtrnIntervalMs == 0)
7282 {
7283 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7284 goto fail;
7285 }
7286
7287 if (!tb[PARAM_SRC_MAC_ADDR])
7288 {
7289 hddLog(LOGE, FL("attr source mac address failed"));
7290 goto fail;
7291 }
7292 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7293 VOS_MAC_ADDR_SIZE);
7294 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7295 MAC_ADDR_ARRAY(add_req->macAddress));
7296
7297 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7298 VOS_MAC_ADDR_SIZE))
7299 {
7300 hddLog(LOGE,
7301 FL("input src mac address and connected ap bssid are different"));
7302 goto fail;
7303 }
7304
7305 if (!tb[PARAM_DST_MAC_ADDR])
7306 {
7307 hddLog(LOGE, FL("attr dst mac address failed"));
7308 goto fail;
7309 }
7310 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7311 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7312 MAC_ADDR_ARRAY(dst_addr.bytes));
7313
7314 if (!tb[PARAM_IP_PACKET])
7315 {
7316 hddLog(LOGE, FL("attr ip packet failed"));
7317 goto fail;
7318 }
7319 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7320 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7321
7322 if (add_req->ucPtrnSize < 0 ||
7323 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7324 HDD_ETH_HEADER_LEN))
7325 {
7326 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7327 add_req->ucPtrnSize);
7328 goto fail;
7329 }
7330
7331 len = 0;
7332 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7333 len += VOS_MAC_ADDR_SIZE;
7334 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7335 VOS_MAC_ADDR_SIZE);
7336 len += VOS_MAC_ADDR_SIZE;
7337 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7338 len += 2;
7339
7340 /*
7341 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7342 * ------------------------------------------------------------
7343 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7344 * ------------------------------------------------------------
7345 */
7346 vos_mem_copy(&add_req->ucPattern[len],
7347 nla_data(tb[PARAM_IP_PACKET]),
7348 add_req->ucPtrnSize);
7349 add_req->ucPtrnSize += len;
7350
7351 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7352 add_req->ucPattern, add_req->ucPtrnSize);
7353
7354 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7355 if (ret)
7356 {
7357 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7358 goto fail;
7359 }
7360 add_req->ucPtrnId = pattern_id;
7361 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7362
7363 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7364 if (!HAL_STATUS_SUCCESS(status))
7365 {
7366 hddLog(LOGE,
7367 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7368 goto fail;
7369 }
7370
7371 EXIT();
7372 vos_mem_free(add_req);
7373 return 0;
7374
7375fail:
7376 vos_mem_free(add_req);
7377 return -EINVAL;
7378}
7379
7380/**
7381 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7382 * @adapter: adapter pointer
7383 * @hdd_ctx: hdd context
7384 * @tb: nl attributes
7385 *
7386 * This function reads the NL attributes and forms a DelTxPtrn message
7387 * posts it to SME.
7388 *
7389 */
7390static int
7391wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7392 struct nlattr **tb)
7393{
7394 struct sSirDelPeriodicTxPtrn *del_req;
7395 eHalStatus status;
7396 uint32_t request_id, ret;
7397 uint8_t pattern_id = 0;
7398
7399 /* Parse and fetch request Id */
7400 if (!tb[PARAM_REQUEST_ID])
7401 {
7402 hddLog(LOGE, FL("attr request id failed"));
7403 return -EINVAL;
7404 }
7405 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7406 if (request_id == 0)
7407 {
7408 hddLog(LOGE, FL("request_id cannot be zero"));
7409 return -EINVAL;
7410 }
7411
7412 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7413 if (ret)
7414 {
7415 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7416 return -EINVAL;
7417 }
7418
7419 del_req = vos_mem_malloc(sizeof(*del_req));
7420 if (!del_req)
7421 {
7422 hddLog(LOGE, FL("memory allocation failed"));
7423 return -ENOMEM;
7424 }
7425
7426 vos_mem_set(del_req, sizeof(*del_req), 0);
7427 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7428 VOS_MAC_ADDR_SIZE);
7429 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7430 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7431 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7432 request_id, pattern_id, del_req->ucPatternIdBitmap);
7433
7434 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7435 if (!HAL_STATUS_SUCCESS(status))
7436 {
7437 hddLog(LOGE,
7438 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7439 goto fail;
7440 }
7441
7442 EXIT();
7443 vos_mem_free(del_req);
7444 return 0;
7445
7446fail:
7447 vos_mem_free(del_req);
7448 return -EINVAL;
7449}
7450
7451
7452/**
7453 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7454 * @wiphy: Pointer to wireless phy
7455 * @wdev: Pointer to wireless device
7456 * @data: Pointer to data
7457 * @data_len: Data length
7458 *
7459 * Return: 0 on success, negative errno on failure
7460 */
7461static int
7462__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7463 struct wireless_dev *wdev,
7464 const void *data,
7465 int data_len)
7466{
7467 struct net_device *dev = wdev->netdev;
7468 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7469 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7470 struct nlattr *tb[PARAM_MAX + 1];
7471 uint8_t control;
7472 int ret;
7473 static const struct nla_policy policy[PARAM_MAX + 1] =
7474 {
7475 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7476 [PARAM_CONTROL] = { .type = NLA_U32 },
7477 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7478 .len = VOS_MAC_ADDR_SIZE },
7479 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7480 .len = VOS_MAC_ADDR_SIZE },
7481 [PARAM_PERIOD] = { .type = NLA_U32 },
7482 };
7483
7484 ENTER();
7485
7486 ret = wlan_hdd_validate_context(hdd_ctx);
7487 if (0 != ret)
7488 {
7489 hddLog(LOGE, FL("HDD context is not valid"));
7490 return ret;
7491 }
7492
7493 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7494 {
7495 hddLog(LOGE,
7496 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7497 return -ENOTSUPP;
7498 }
7499
7500 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7501 {
7502 hddLog(LOGE, FL("Invalid ATTR"));
7503 return -EINVAL;
7504 }
7505
7506 if (!tb[PARAM_CONTROL])
7507 {
7508 hddLog(LOGE, FL("attr control failed"));
7509 return -EINVAL;
7510 }
7511 control = nla_get_u32(tb[PARAM_CONTROL]);
7512 hddLog(LOG1, FL("Control: %d"), control);
7513
7514 if (control == WLAN_START_OFFLOADED_PACKETS)
7515 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7516 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7517 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7518 else
7519 {
7520 hddLog(LOGE, FL("Invalid control: %d"), control);
7521 return -EINVAL;
7522 }
7523}
7524
7525/*
7526 * done with short names for the global vendor params
7527 * used by __wlan_hdd_cfg80211_offloaded_packets()
7528 */
7529#undef PARAM_MAX
7530#undef PARAM_REQUEST_ID
7531#undef PARAM_CONTROL
7532#undef PARAM_IP_PACKET
7533#undef PARAM_SRC_MAC_ADDR
7534#undef PARAM_DST_MAC_ADDR
7535#undef PARAM_PERIOD
7536
7537/**
7538 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7539 * @wiphy: wiphy structure pointer
7540 * @wdev: Wireless device structure pointer
7541 * @data: Pointer to the data received
7542 * @data_len: Length of @data
7543 *
7544 * Return: 0 on success; errno on failure
7545 */
7546static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7547 struct wireless_dev *wdev,
7548 const void *data,
7549 int data_len)
7550{
7551 int ret = 0;
7552
7553 vos_ssr_protect(__func__);
7554 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7555 wdev, data, data_len);
7556 vos_ssr_unprotect(__func__);
7557
7558 return ret;
7559}
7560#endif
7561
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307562static const struct
7563nla_policy
7564qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307565 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7566 .type = NLA_BINARY,
7567 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307568};
7569
7570/**
7571 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7572 * get link properties like nss, rate flags and operating frequency for
7573 * the connection with the given peer.
7574 * @wiphy: WIPHY structure pointer
7575 * @wdev: Wireless device structure pointer
7576 * @data: Pointer to the data received
7577 * @data_len: Length of the data received
7578 *
7579 * This function return the above link properties on success.
7580 *
7581 * Return: 0 on success and errno on failure
7582 */
7583static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7584 struct wireless_dev *wdev,
7585 const void *data,
7586 int data_len)
7587{
7588 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7589 struct net_device *dev = wdev->netdev;
7590 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7591 hdd_station_ctx_t *hdd_sta_ctx;
7592 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7593 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7594 uint32_t sta_id;
7595 struct sk_buff *reply_skb;
7596 uint32_t rate_flags = 0;
7597 uint8_t nss;
7598 uint8_t final_rate_flags = 0;
7599 uint32_t freq;
7600 v_CONTEXT_t pVosContext = NULL;
7601 ptSapContext pSapCtx = NULL;
7602
7603 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7604 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7605 return -EINVAL;
7606 }
7607
7608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7609 qca_wlan_vendor_attr_policy)) {
7610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7611 return -EINVAL;
7612 }
7613
7614 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7615 hddLog(VOS_TRACE_LEVEL_ERROR,
7616 FL("Attribute peerMac not provided for mode=%d"),
7617 adapter->device_mode);
7618 return -EINVAL;
7619 }
7620
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307621 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7622 hddLog(VOS_TRACE_LEVEL_ERROR,
7623 FL("Attribute peerMac is invalid=%d"),
7624 adapter->device_mode);
7625 return -EINVAL;
7626 }
7627
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307628 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7629 sizeof(peer_mac));
7630 hddLog(VOS_TRACE_LEVEL_INFO,
7631 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7632 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7633
7634 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7635 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7636 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7637 if ((hdd_sta_ctx->conn_info.connState !=
7638 eConnectionState_Associated) ||
7639 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7640 VOS_MAC_ADDRESS_LEN)) {
7641 hddLog(VOS_TRACE_LEVEL_ERROR,
7642 FL("Not Associated to mac "MAC_ADDRESS_STR),
7643 MAC_ADDR_ARRAY(peer_mac));
7644 return -EINVAL;
7645 }
7646
7647 nss = 1; //pronto supports only one spatial stream
7648 freq = vos_chan_to_freq(
7649 hdd_sta_ctx->conn_info.operationChannel);
7650 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7651
7652 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7653 adapter->device_mode == WLAN_HDD_SOFTAP) {
7654
7655 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7656 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7657 if(pSapCtx == NULL){
7658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7659 FL("psapCtx is NULL"));
7660 return -ENOENT;
7661 }
7662
7663
7664 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7665 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7666 !vos_is_macaddr_broadcast(
7667 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7668 vos_mem_compare(
7669 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7670 peer_mac, VOS_MAC_ADDRESS_LEN))
7671 break;
7672 }
7673
7674 if (WLAN_MAX_STA_COUNT == sta_id) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("No active peer with mac="MAC_ADDRESS_STR),
7677 MAC_ADDR_ARRAY(peer_mac));
7678 return -EINVAL;
7679 }
7680
7681 nss = 1; //pronto supports only one spatial stream
7682 freq = vos_chan_to_freq(
7683 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7684 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7685 } else {
7686 hddLog(VOS_TRACE_LEVEL_ERROR,
7687 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7688 MAC_ADDR_ARRAY(peer_mac));
7689 return -EINVAL;
7690 }
7691
7692 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7693 if (rate_flags & eHAL_TX_RATE_VHT80) {
7694 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307695#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7696 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307697 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307698#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307699 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7700 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307701#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7702 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307703 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307704#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307705 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7706 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7707 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7708 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307709#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7710 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307711 if (rate_flags & eHAL_TX_RATE_HT40)
7712 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307713#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307714 }
7715
7716 if (rate_flags & eHAL_TX_RATE_SGI) {
7717 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7718 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7719 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7720 }
7721 }
7722
7723 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7724 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7725
7726 if (NULL == reply_skb) {
7727 hddLog(VOS_TRACE_LEVEL_ERROR,
7728 FL("getLinkProperties: skb alloc failed"));
7729 return -EINVAL;
7730 }
7731
7732 if (nla_put_u8(reply_skb,
7733 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7734 nss) ||
7735 nla_put_u8(reply_skb,
7736 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7737 final_rate_flags) ||
7738 nla_put_u32(reply_skb,
7739 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7740 freq)) {
7741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7742 kfree_skb(reply_skb);
7743 return -EINVAL;
7744 }
7745
7746 return cfg80211_vendor_cmd_reply(reply_skb);
7747}
7748
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307749#define BEACON_MISS_THRESH_2_4 \
7750 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7751#define BEACON_MISS_THRESH_5_0 \
7752 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307753#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7754#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7755#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7756#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307757#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7758 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307759#define PARAM_FORCE_RSN_IE \
7760 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307761/*
7762 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7763 * @hdd_ctx: hdd context
7764 * @enable: Value received in the command, 1 for disable and 2 for enable
7765 *
7766 * Return: void
7767 */
7768static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7769{
7770 if (!hdd_ctx) {
7771 hddLog(LOGE, "hdd_ctx NULL");
7772 return;
7773 }
7774
7775 sme_set_qpower(hdd_ctx->hHal, enable);
7776}
7777
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307778/**
7779 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7780 * vendor command
7781 *
7782 * @wiphy: wiphy device pointer
7783 * @wdev: wireless device pointer
7784 * @data: Vendor command data buffer
7785 * @data_len: Buffer length
7786 *
7787 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7788 *
7789 * Return: EOK or other error codes.
7790 */
7791
7792static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7793 struct wireless_dev *wdev,
7794 const void *data,
7795 int data_len)
7796{
7797 struct net_device *dev = wdev->netdev;
7798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7799 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7800 hdd_station_ctx_t *pHddStaCtx;
7801 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7802 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307803 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307804 eHalStatus status;
7805 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307806 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307807 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307808
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307809 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7810 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7811 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307812 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7813 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7814 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307815 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7816 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307817 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307818 };
7819
7820 ENTER();
7821
7822 if (VOS_FTM_MODE == hdd_get_conparam()) {
7823 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7824 return -EINVAL;
7825 }
7826
7827 ret_val = wlan_hdd_validate_context(pHddCtx);
7828 if (ret_val) {
7829 return ret_val;
7830 }
7831
7832 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7833
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307834 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7835 hddLog(LOGE, FL("Invalid ATTR"));
7836 return -EINVAL;
7837 }
7838
7839 /* check the Wifi Capability */
7840 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7841 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7842 {
7843 hddLog(VOS_TRACE_LEVEL_ERROR,
7844 FL("WIFICONFIG not supported by Firmware"));
7845 return -EINVAL;
7846 }
7847
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307848 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7849 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7850 modifyRoamParamsReq.value =
7851 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7852
7853 if (eHAL_STATUS_SUCCESS !=
7854 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7855 {
7856 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7857 ret_val = -EINVAL;
7858 }
7859 return ret_val;
7860 }
7861
7862 /* Moved this down in order to provide provision to set beacon
7863 * miss penalty count irrespective of connection state.
7864 */
7865 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7866 hddLog(LOGE, FL("Not in Connected state!"));
7867 return -ENOTSUPP;
7868 }
7869
7870 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307871
7872 if (!pReq) {
7873 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7874 "%s: Not able to allocate memory for tSetWifiConfigParams",
7875 __func__);
7876 return eHAL_STATUS_E_MALLOC_FAILED;
7877 }
7878
7879 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7880
7881 pReq->sessionId = pAdapter->sessionId;
7882 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7883
7884 if (tb[PARAM_MODULATED_DTIM]) {
7885 pReq->paramValue = nla_get_u32(
7886 tb[PARAM_MODULATED_DTIM]);
7887 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7888 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307889 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307890 hdd_set_pwrparams(pHddCtx);
7891 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7892 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7893
7894 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7895 iw_full_power_cbfn, pAdapter,
7896 eSME_FULL_PWR_NEEDED_BY_HDD);
7897 }
7898 else
7899 {
7900 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7901 }
7902 }
7903
7904 if (tb[PARAM_STATS_AVG_FACTOR]) {
7905 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7906 pReq->paramValue = nla_get_u16(
7907 tb[PARAM_STATS_AVG_FACTOR]);
7908 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7909 pReq->paramType, pReq->paramValue);
7910 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7911
7912 if (eHAL_STATUS_SUCCESS != status)
7913 {
7914 vos_mem_free(pReq);
7915 pReq = NULL;
7916 ret_val = -EPERM;
7917 return ret_val;
7918 }
7919 }
7920
7921
7922 if (tb[PARAM_GUARD_TIME]) {
7923 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7924 pReq->paramValue = nla_get_u32(
7925 tb[PARAM_GUARD_TIME]);
7926 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7927 pReq->paramType, pReq->paramValue);
7928 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7929
7930 if (eHAL_STATUS_SUCCESS != status)
7931 {
7932 vos_mem_free(pReq);
7933 pReq = NULL;
7934 ret_val = -EPERM;
7935 return ret_val;
7936 }
7937
7938 }
7939
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307940 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7941 hb_thresh_val = nla_get_u8(
7942 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7943
7944 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7945 hb_thresh_val);
7946 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7947 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7948 NULL, eANI_BOOLEAN_FALSE);
7949
7950 status = sme_update_hb_threshold(
7951 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7952 WNI_CFG_HEART_BEAT_THRESHOLD,
7953 hb_thresh_val, eCSR_BAND_24);
7954 if (eHAL_STATUS_SUCCESS != status) {
7955 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7956 vos_mem_free(pReq);
7957 pReq = NULL;
7958 return -EPERM;
7959 }
7960 }
7961
7962 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7963 hb_thresh_val = nla_get_u8(
7964 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7965
7966 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7967 hb_thresh_val);
7968 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7969 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7970 NULL, eANI_BOOLEAN_FALSE);
7971
7972 status = sme_update_hb_threshold(
7973 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7974 WNI_CFG_HEART_BEAT_THRESHOLD,
7975 hb_thresh_val, eCSR_BAND_5G);
7976 if (eHAL_STATUS_SUCCESS != status) {
7977 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7978 vos_mem_free(pReq);
7979 pReq = NULL;
7980 return -EPERM;
7981 }
7982 }
7983
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307984 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
7985 qpower = nla_get_u8(
7986 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
7987
7988 if(qpower > 1) {
7989 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
7990 vos_mem_free(pReq);
7991 pReq = NULL;
7992 return -EINVAL;
7993 }
7994 /* FW is expacting qpower as 1 for Disable and 2 for enable */
7995 qpower++;
7996 hdd_set_qpower(pHddCtx, qpower);
7997 }
7998
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307999 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8000 pHddCtx->cfg_ini->force_rsne_override) {
8001 uint8_t force_rsne_override;
8002
8003 force_rsne_override =
8004 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8005 if (force_rsne_override > 1) {
8006 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8007 ret_val = -EINVAL;
8008 }
8009 pHddCtx->force_rsne_override = force_rsne_override;
8010 hddLog(LOG1, "force_rsne_override - %d",
8011 pHddCtx->force_rsne_override);
8012 }
8013
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308014 EXIT();
8015 return ret_val;
8016}
8017
8018/**
8019 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8020 * vendor command
8021 *
8022 * @wiphy: wiphy device pointer
8023 * @wdev: wireless device pointer
8024 * @data: Vendor command data buffer
8025 * @data_len: Buffer length
8026 *
8027 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8028 *
8029 * Return: EOK or other error codes.
8030 */
8031static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8032 struct wireless_dev *wdev,
8033 const void *data,
8034 int data_len)
8035{
8036 int ret;
8037
8038 vos_ssr_protect(__func__);
8039 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8040 data, data_len);
8041 vos_ssr_unprotect(__func__);
8042
8043 return ret;
8044}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308045
8046/*
8047 * define short names for the global vendor params
8048 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8049 */
8050#define STATS_SET_INVALID \
8051 QCA_ATTR_NUD_STATS_SET_INVALID
8052#define STATS_SET_START \
8053 QCA_ATTR_NUD_STATS_SET_START
8054#define STATS_GW_IPV4 \
8055 QCA_ATTR_NUD_STATS_GW_IPV4
8056#define STATS_SET_MAX \
8057 QCA_ATTR_NUD_STATS_SET_MAX
8058
8059const struct nla_policy
8060qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8061{
8062 [STATS_SET_START] = {.type = NLA_FLAG },
8063 [STATS_GW_IPV4] = {.type = NLA_U32 },
8064};
8065
8066/**
8067 * hdd_set_nud_stats_cb() - hdd callback api to get status
8068 * @data: pointer to adapter
8069 * @rsp: status
8070 *
8071 * Return: None
8072 */
8073static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8074{
8075
8076 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8077
8078 if (NULL == adapter)
8079 return;
8080
8081 if (VOS_STATUS_SUCCESS == rsp) {
8082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8083 "%s success received STATS_SET_START", __func__);
8084 } else {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8086 "%s STATS_SET_START Failed!!", __func__);
8087 }
8088 return;
8089}
8090
8091/**
8092 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8093 * @wiphy: pointer to wireless wiphy structure.
8094 * @wdev: pointer to wireless_dev structure.
8095 * @data: pointer to apfind configuration data.
8096 * @data_len: the length in byte of apfind data.
8097 *
8098 * This is called when wlan driver needs to send arp stats to
8099 * firmware.
8100 *
8101 * Return: An error code or 0 on success.
8102 */
8103static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8104 struct wireless_dev *wdev,
8105 const void *data, int data_len)
8106{
8107 struct nlattr *tb[STATS_SET_MAX + 1];
8108 struct net_device *dev = wdev->netdev;
8109 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8110 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308111 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308112 setArpStatsParams arp_stats_params;
8113 int err = 0;
8114
8115 ENTER();
8116
8117 err = wlan_hdd_validate_context(hdd_ctx);
8118 if (0 != err)
8119 return err;
8120
8121 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8123 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8124 return -EINVAL;
8125 }
8126
8127 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8128 qca_wlan_vendor_set_nud_stats);
8129 if (err)
8130 {
8131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8132 "%s STATS_SET_START ATTR", __func__);
8133 return err;
8134 }
8135
8136 if (tb[STATS_SET_START])
8137 {
8138 if (!tb[STATS_GW_IPV4]) {
8139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8140 "%s STATS_SET_START CMD", __func__);
8141 return -EINVAL;
8142 }
8143 arp_stats_params.flag = true;
8144 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8145 } else {
8146 arp_stats_params.flag = false;
8147 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308148 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8150 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8152 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308153
8154 arp_stats_params.pkt_type = 1; // ARP packet type
8155
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308156 if (arp_stats_params.flag) {
8157 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8158 WLANTL_SetARPFWDatapath(pVosContext, true);
8159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8160 "%s Set FW in data path for ARP with tgt IP :%d",
8161 __func__, hdd_ctx->track_arp_ip);
8162 }
8163 else {
8164 WLANTL_SetARPFWDatapath(pVosContext, false);
8165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8166 "%s Remove FW from data path", __func__);
8167 }
8168
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308169 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8170 arp_stats_params.data_ctx = adapter;
8171
8172 if (eHAL_STATUS_SUCCESS !=
8173 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8175 "%s STATS_SET_START CMD Failed!!", __func__);
8176 return -EINVAL;
8177 }
8178
8179 EXIT();
8180
8181 return err;
8182}
8183
8184/**
8185 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8186 * @wiphy: pointer to wireless wiphy structure.
8187 * @wdev: pointer to wireless_dev structure.
8188 * @data: pointer to apfind configuration data.
8189 * @data_len: the length in byte of apfind data.
8190 *
8191 * This is called when wlan driver needs to send arp stats to
8192 * firmware.
8193 *
8194 * Return: An error code or 0 on success.
8195 */
8196static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8197 struct wireless_dev *wdev,
8198 const void *data, int data_len)
8199{
8200 int ret;
8201
8202 vos_ssr_protect(__func__);
8203 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8204 vos_ssr_unprotect(__func__);
8205
8206 return ret;
8207}
8208#undef STATS_SET_INVALID
8209#undef STATS_SET_START
8210#undef STATS_GW_IPV4
8211#undef STATS_SET_MAX
8212
8213/*
8214 * define short names for the global vendor params
8215 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8216 */
8217#define STATS_GET_INVALID \
8218 QCA_ATTR_NUD_STATS_SET_INVALID
8219#define COUNT_FROM_NETDEV \
8220 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8221#define COUNT_TO_LOWER_MAC \
8222 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8223#define RX_COUNT_BY_LOWER_MAC \
8224 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8225#define COUNT_TX_SUCCESS \
8226 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8227#define RSP_RX_COUNT_BY_LOWER_MAC \
8228 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8229#define RSP_RX_COUNT_BY_UPPER_MAC \
8230 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8231#define RSP_COUNT_TO_NETDEV \
8232 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8233#define RSP_COUNT_OUT_OF_ORDER_DROP \
8234 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8235#define AP_LINK_ACTIVE \
8236 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8237#define AP_LINK_DAD \
8238 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8239#define STATS_GET_MAX \
8240 QCA_ATTR_NUD_STATS_GET_MAX
8241
8242const struct nla_policy
8243qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8244{
8245 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8246 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8247 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8248 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8249 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8250 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8251 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8252 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8253 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8254 [AP_LINK_DAD] = {.type = NLA_FLAG },
8255};
8256
8257static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8258{
8259
8260 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308261 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308262 struct hdd_nud_stats_context *context;
8263 int status;
8264
8265 ENTER();
8266
8267 if (NULL == adapter)
8268 return;
8269
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308270 if (!rsp) {
8271 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308272 return;
8273 }
8274
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308275 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8276 status = wlan_hdd_validate_context(hdd_ctx);
8277 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308278 return;
8279 }
8280
8281 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8282 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8283 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8284 adapter->dad |= rsp->dad;
8285
8286 spin_lock(&hdd_context_lock);
8287 context = &hdd_ctx->nud_stats_context;
8288 complete(&context->response_event);
8289 spin_unlock(&hdd_context_lock);
8290
8291 return;
8292}
8293static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8294 struct wireless_dev *wdev,
8295 const void *data, int data_len)
8296{
8297 int err = 0;
8298 unsigned long rc;
8299 struct hdd_nud_stats_context *context;
8300 struct net_device *dev = wdev->netdev;
8301 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8302 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8303 getArpStatsParams arp_stats_params;
8304 struct sk_buff *skb;
8305
8306 ENTER();
8307
8308 err = wlan_hdd_validate_context(hdd_ctx);
8309 if (0 != err)
8310 return err;
8311
8312 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8313 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8314 arp_stats_params.data_ctx = adapter;
8315
8316 spin_lock(&hdd_context_lock);
8317 context = &hdd_ctx->nud_stats_context;
8318 INIT_COMPLETION(context->response_event);
8319 spin_unlock(&hdd_context_lock);
8320
8321 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8323 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8324 return -EINVAL;
8325 }
8326
8327 if (eHAL_STATUS_SUCCESS !=
8328 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8330 "%s STATS_SET_START CMD Failed!!", __func__);
8331 return -EINVAL;
8332 }
8333
8334 rc = wait_for_completion_timeout(&context->response_event,
8335 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8336 if (!rc)
8337 {
8338 hddLog(LOGE,
8339 FL("Target response timed out request "));
8340 return -ETIMEDOUT;
8341 }
8342
8343 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8344 WLAN_NUD_STATS_LEN);
8345 if (!skb)
8346 {
8347 hddLog(VOS_TRACE_LEVEL_ERROR,
8348 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8349 __func__);
8350 return -ENOMEM;
8351 }
8352
8353 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8354 adapter->hdd_stats.hddArpStats.txCount) ||
8355 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8356 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8357 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8358 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8359 nla_put_u16(skb, COUNT_TX_SUCCESS,
8360 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8361 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8362 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8363 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8364 adapter->hdd_stats.hddArpStats.rxCount) ||
8365 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8366 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8367 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8368 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8369 hddLog(LOGE, FL("nla put fail"));
8370 kfree_skb(skb);
8371 return -EINVAL;
8372 }
8373 if (adapter->con_status)
8374 nla_put_flag(skb, AP_LINK_ACTIVE);
8375 if (adapter->dad)
8376 nla_put_flag(skb, AP_LINK_DAD);
8377
8378 cfg80211_vendor_cmd_reply(skb);
8379 return err;
8380}
8381
8382static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8383 struct wireless_dev *wdev,
8384 const void *data, int data_len)
8385{
8386 int ret;
8387
8388 vos_ssr_protect(__func__);
8389 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8390 vos_ssr_unprotect(__func__);
8391
8392 return ret;
8393}
8394
8395#undef QCA_ATTR_NUD_STATS_SET_INVALID
8396#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8397#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8398#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8400#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8404#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8405#undef QCA_ATTR_NUD_STATS_GET_MAX
8406
8407
8408
Kapil Guptaee33bf12016-12-20 18:27:37 +05308409#ifdef WLAN_FEATURE_APFIND
8410/**
8411 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8412 * @wiphy: pointer to wireless wiphy structure.
8413 * @wdev: pointer to wireless_dev structure.
8414 * @data: pointer to apfind configuration data.
8415 * @data_len: the length in byte of apfind data.
8416 *
8417 * This is called when wlan driver needs to send APFIND configurations to
8418 * firmware.
8419 *
8420 * Return: An error code or 0 on success.
8421 */
8422static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8423 struct wireless_dev *wdev,
8424 const void *data, int data_len)
8425{
8426 struct sme_ap_find_request_req apfind_req;
8427 VOS_STATUS status;
8428 int ret_val;
8429 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8430
8431 ENTER();
8432
8433 ret_val = wlan_hdd_validate_context(hdd_ctx);
8434 if (ret_val)
8435 return ret_val;
8436
8437 if (VOS_FTM_MODE == hdd_get_conparam()) {
8438 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8439 return -EPERM;
8440 }
8441
8442 apfind_req.request_data_len = data_len;
8443 apfind_req.request_data = data;
8444
8445 status = sme_apfind_set_cmd(&apfind_req);
8446 if (VOS_STATUS_SUCCESS != status) {
8447 ret_val = -EIO;
8448 }
8449 return ret_val;
8450}
8451
8452/**
8453 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8454 * @wiphy: pointer to wireless wiphy structure.
8455 * @wdev: pointer to wireless_dev structure.
8456 * @data: pointer to apfind configuration data.
8457 * @data_len: the length in byte of apfind data.
8458 *
8459 * This is called when wlan driver needs to send APFIND configurations to
8460 * firmware.
8461 *
8462 * Return: An error code or 0 on success.
8463 */
8464static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8465 struct wireless_dev *wdev,
8466 const void *data, int data_len)
8467{
8468 int ret;
8469
8470 vos_ssr_protect(__func__);
8471 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8472 vos_ssr_unprotect(__func__);
8473
8474 return ret;
8475}
8476#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308477
8478/**
8479 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8480 * @wiphy: pointer to wireless wiphy structure.
8481 * @wdev: pointer to wireless_dev structure.
8482 * @data: Pointer to the data to be passed via vendor interface
8483 * @data_len:Length of the data to be passed
8484 *
8485 * This is called by userspace to know the supported logger features
8486 *
8487 * Return: Return the Success or Failure code.
8488 */
8489static int
8490__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8491 struct wireless_dev *wdev,
8492 const void *data, int data_len)
8493{
8494 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8495 int status;
8496 uint32_t features;
8497 struct sk_buff *reply_skb = NULL;
8498
8499 if (VOS_FTM_MODE == hdd_get_conparam()) {
8500 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8501 return -EINVAL;
8502 }
8503
8504 status = wlan_hdd_validate_context(hdd_ctx);
8505 if (0 != status)
8506 return -EINVAL;
8507
8508 features = 0;
8509
8510 if (hdd_is_memdump_supported())
8511 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8512
8513 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8514 hdd_ctx->cfg_ini->enableFatalEvent &&
8515 hdd_ctx->is_fatal_event_log_sup) {
8516 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8517 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8518 }
8519
8520 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8521 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8522 if (!reply_skb) {
8523 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8524 return -ENOMEM;
8525 }
8526
8527 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8528 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8529 features)) {
8530 hddLog(LOGE, FL("nla put fail"));
8531 kfree_skb(reply_skb);
8532 return -EINVAL;
8533 }
8534
8535 return cfg80211_vendor_cmd_reply(reply_skb);
8536}
8537
8538/**
8539 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8540 * @wiphy: pointer to wireless wiphy structure.
8541 * @wdev: pointer to wireless_dev structure.
8542 * @data: Pointer to the data to be passed via vendor interface
8543 * @data_len:Length of the data to be passed
8544 *
8545 * This is called by userspace to know the supported logger features
8546 *
8547 * Return: Return the Success or Failure code.
8548 */
8549static int
8550wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8551 struct wireless_dev *wdev,
8552 const void *data, int data_len)
8553{
8554 int ret;
8555
8556 vos_ssr_protect(__func__);
8557 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8558 data, data_len);
8559 vos_ssr_unprotect(__func__);
8560
8561 return ret;
8562}
8563
Sunil Duttc69bccb2014-05-26 21:30:20 +05308564const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8565{
Mukul Sharma2a271632014-10-13 14:59:01 +05308566 {
8567 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8568 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8569 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8570 WIPHY_VENDOR_CMD_NEED_NETDEV |
8571 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308572 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308573 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308574
8575 {
8576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8579 WIPHY_VENDOR_CMD_NEED_NETDEV |
8580 WIPHY_VENDOR_CMD_NEED_RUNNING,
8581 .doit = wlan_hdd_cfg80211_nan_request
8582 },
8583
Sunil Duttc69bccb2014-05-26 21:30:20 +05308584#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8585 {
8586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8589 WIPHY_VENDOR_CMD_NEED_NETDEV |
8590 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308591 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308592 },
8593
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308601 },
8602
8603 {
8604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8607 WIPHY_VENDOR_CMD_NEED_NETDEV |
8608 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308609 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308610 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308611#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308612#ifdef WLAN_FEATURE_EXTSCAN
8613 {
8614 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8615 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8616 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8617 WIPHY_VENDOR_CMD_NEED_NETDEV |
8618 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308619 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308620 },
8621 {
8622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8625 WIPHY_VENDOR_CMD_NEED_NETDEV |
8626 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308627 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308628 },
8629 {
8630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8631 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8632 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8633 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308634 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308635 },
8636 {
8637 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8638 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8639 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8640 WIPHY_VENDOR_CMD_NEED_NETDEV |
8641 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308642 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308643 },
8644 {
8645 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8646 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8647 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8648 WIPHY_VENDOR_CMD_NEED_NETDEV |
8649 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308650 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308651 },
8652 {
8653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8655 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8656 WIPHY_VENDOR_CMD_NEED_NETDEV |
8657 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308658 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308659 },
8660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV |
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308666 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308667 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308668#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308669/*EXT TDLS*/
8670 {
8671 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8672 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8673 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8674 WIPHY_VENDOR_CMD_NEED_NETDEV |
8675 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308676 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308677 },
8678 {
8679 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8680 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8681 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8682 WIPHY_VENDOR_CMD_NEED_NETDEV |
8683 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308684 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308685 },
8686 {
8687 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8688 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8689 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8690 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308691 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308692 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308693 {
8694 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8695 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8696 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8697 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308698 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308699 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308700 {
8701 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8702 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8703 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8704 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308705 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308706 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308707 {
8708 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8709 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8710 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8711 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308712 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308713 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308714 {
8715 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8716 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8717 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8718 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308719 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308720 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308721 {
8722 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308723 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8724 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8725 WIPHY_VENDOR_CMD_NEED_NETDEV |
8726 WIPHY_VENDOR_CMD_NEED_RUNNING,
8727 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8728 },
8729 {
8730 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308731 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8732 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8733 WIPHY_VENDOR_CMD_NEED_NETDEV |
8734 WIPHY_VENDOR_CMD_NEED_RUNNING,
8735 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308736 },
8737 {
8738 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8739 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8740 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8741 WIPHY_VENDOR_CMD_NEED_NETDEV,
8742 .doit = wlan_hdd_cfg80211_wifi_logger_start
8743 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308744 {
8745 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8746 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8747 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8748 WIPHY_VENDOR_CMD_NEED_NETDEV|
8749 WIPHY_VENDOR_CMD_NEED_RUNNING,
8750 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308751 },
8752 {
8753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8756 WIPHY_VENDOR_CMD_NEED_NETDEV |
8757 WIPHY_VENDOR_CMD_NEED_RUNNING,
8758 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308759 },
8760 {
8761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8764 WIPHY_VENDOR_CMD_NEED_NETDEV |
8765 WIPHY_VENDOR_CMD_NEED_RUNNING,
8766 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308767 },
8768#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8769 {
8770 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8771 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8772 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8773 WIPHY_VENDOR_CMD_NEED_NETDEV |
8774 WIPHY_VENDOR_CMD_NEED_RUNNING,
8775 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308776 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308777#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308778 {
8779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8782 WIPHY_VENDOR_CMD_NEED_NETDEV |
8783 WIPHY_VENDOR_CMD_NEED_RUNNING,
8784 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308785 },
8786 {
8787 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8788 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8789 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8790 WIPHY_VENDOR_CMD_NEED_NETDEV |
8791 WIPHY_VENDOR_CMD_NEED_RUNNING,
8792 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308793 },
8794#ifdef WLAN_FEATURE_APFIND
8795 {
8796 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8797 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8798 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8799 WIPHY_VENDOR_CMD_NEED_NETDEV,
8800 .doit = wlan_hdd_cfg80211_apfind_cmd
8801 },
8802#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308803 {
8804 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8805 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8806 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8807 WIPHY_VENDOR_CMD_NEED_NETDEV |
8808 WIPHY_VENDOR_CMD_NEED_RUNNING,
8809 .doit = wlan_hdd_cfg80211_set_nud_stats
8810 },
8811 {
8812 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8813 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8814 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8815 WIPHY_VENDOR_CMD_NEED_NETDEV |
8816 WIPHY_VENDOR_CMD_NEED_RUNNING,
8817 .doit = wlan_hdd_cfg80211_get_nud_stats
8818 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308819 {
8820 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8821 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8822 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8823 WIPHY_VENDOR_CMD_NEED_NETDEV |
8824 WIPHY_VENDOR_CMD_NEED_RUNNING,
8825 .doit = hdd_cfg80211_get_station_cmd
8826 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308827 {
8828 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8829 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8830 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308831 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308832 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8833 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308834};
8835
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008836/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308837static const
8838struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008839{
8840#ifdef FEATURE_WLAN_CH_AVOID
8841 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308842 .vendor_id = QCA_NL80211_VENDOR_ID,
8843 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008844 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308845#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8846#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8847 {
8848 /* Index = 1*/
8849 .vendor_id = QCA_NL80211_VENDOR_ID,
8850 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8851 },
8852 {
8853 /* Index = 2*/
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8856 },
8857 {
8858 /* Index = 3*/
8859 .vendor_id = QCA_NL80211_VENDOR_ID,
8860 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8861 },
8862 {
8863 /* Index = 4*/
8864 .vendor_id = QCA_NL80211_VENDOR_ID,
8865 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8866 },
8867 {
8868 /* Index = 5*/
8869 .vendor_id = QCA_NL80211_VENDOR_ID,
8870 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8871 },
8872 {
8873 /* Index = 6*/
8874 .vendor_id = QCA_NL80211_VENDOR_ID,
8875 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8876 },
8877#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308878#ifdef WLAN_FEATURE_EXTSCAN
8879 {
8880 .vendor_id = QCA_NL80211_VENDOR_ID,
8881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8882 },
8883 {
8884 .vendor_id = QCA_NL80211_VENDOR_ID,
8885 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8886 },
8887 {
8888 .vendor_id = QCA_NL80211_VENDOR_ID,
8889 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8890 },
8891 {
8892 .vendor_id = QCA_NL80211_VENDOR_ID,
8893 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8894 },
8895 {
8896 .vendor_id = QCA_NL80211_VENDOR_ID,
8897 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8898 },
8899 {
8900 .vendor_id = QCA_NL80211_VENDOR_ID,
8901 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8902 },
8903 {
8904 .vendor_id = QCA_NL80211_VENDOR_ID,
8905 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8906 },
8907 {
8908 .vendor_id = QCA_NL80211_VENDOR_ID,
8909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8910 },
8911 {
8912 .vendor_id = QCA_NL80211_VENDOR_ID,
8913 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8914 },
8915 {
8916 .vendor_id = QCA_NL80211_VENDOR_ID,
8917 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8918 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308919#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308920/*EXT TDLS*/
8921 {
8922 .vendor_id = QCA_NL80211_VENDOR_ID,
8923 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8924 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308925 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8926 .vendor_id = QCA_NL80211_VENDOR_ID,
8927 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8928 },
8929
Srinivas Dasari030bad32015-02-18 23:23:54 +05308930
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308931 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308932 .vendor_id = QCA_NL80211_VENDOR_ID,
8933 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8934 },
8935
Sushant Kaushik084f6592015-09-10 13:11:56 +05308936 {
8937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308939 },
8940 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8941 .vendor_id = QCA_NL80211_VENDOR_ID,
8942 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8943 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308944 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8945 .vendor_id = QCA_NL80211_VENDOR_ID,
8946 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8947 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308948 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8949 .vendor_id = QCA_NL80211_VENDOR_ID,
8950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8951 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308952 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8953 .vendor_id = QCA_NL80211_VENDOR_ID,
8954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8955 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308956 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8957 .vendor_id = QCA_NL80211_VENDOR_ID,
8958 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8959 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008960};
8961
Jeff Johnson295189b2012-06-20 16:38:30 -07008962/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308963 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308964 * This function is called by hdd_wlan_startup()
8965 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308966 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308968struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008969{
8970 struct wiphy *wiphy;
8971 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308972 /*
8973 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 */
8975 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8976
8977 if (!wiphy)
8978 {
8979 /* Print error and jump into err label and free the memory */
8980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8981 return NULL;
8982 }
8983
Sunil Duttc69bccb2014-05-26 21:30:20 +05308984
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 return wiphy;
8986}
8987
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308988#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8989 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8990/**
8991 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8992 * @wiphy: pointer to wiphy
8993 * @config: pointer to config
8994 *
8995 * Return: None
8996 */
8997static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8998 hdd_config_t *config)
8999{
9000 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9001 if (config->max_sched_scan_plan_interval)
9002 wiphy->max_sched_scan_plan_interval =
9003 config->max_sched_scan_plan_interval;
9004 if (config->max_sched_scan_plan_iterations)
9005 wiphy->max_sched_scan_plan_iterations =
9006 config->max_sched_scan_plan_iterations;
9007}
9008#else
9009static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9010 hdd_config_t *config)
9011{
9012}
9013#endif
9014
Jeff Johnson295189b2012-06-20 16:38:30 -07009015/*
9016 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309017 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 * private ioctl to change the band value
9019 */
9020int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9021{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309022 int i, j;
9023 eNVChannelEnabledType channelEnabledState;
9024
Jeff Johnsone7245742012-09-05 17:12:55 -07009025 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309026
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309027 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309029
9030 if (NULL == wiphy->bands[i])
9031 {
9032 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9033 __func__, i);
9034 continue;
9035 }
9036
9037 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9038 {
9039 struct ieee80211_supported_band *band = wiphy->bands[i];
9040
9041 channelEnabledState = vos_nv_getChannelEnabledState(
9042 band->channels[j].hw_value);
9043
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309044 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309045 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309046 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309047 continue;
9048 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309049 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309050 {
9051 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9052 continue;
9053 }
9054
9055 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9056 NV_CHANNEL_INVALID == channelEnabledState)
9057 {
9058 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9059 }
9060 else if (NV_CHANNEL_DFS == channelEnabledState)
9061 {
9062 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9063 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9064 }
9065 else
9066 {
9067 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9068 |IEEE80211_CHAN_RADAR);
9069 }
9070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009071 }
9072 return 0;
9073}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309074
9075/**
9076 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9077 * @wiphy: Pointer to the wiphy.
9078 *
9079 * This Function adds Channel Switch support flag, if channel switch is
9080 * supported by kernel.
9081 * Return: void.
9082 */
9083#ifdef CHANNEL_SWITCH_SUPPORTED
9084static inline
9085void hdd_add_channel_switch_support(struct wiphy *wiphy)
9086{
9087 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9088 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9089}
9090#else
9091static inline
9092void hdd_add_channel_switch_support(struct wiphy *wiphy)
9093{
9094}
9095#endif
9096
Jeff Johnson295189b2012-06-20 16:38:30 -07009097/*
9098 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309099 * This function is called by hdd_wlan_startup()
9100 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 * This function is used to initialize and register wiphy structure.
9102 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309103int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 struct wiphy *wiphy,
9105 hdd_config_t *pCfg
9106 )
9107{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309108 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309109 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9110
Jeff Johnsone7245742012-09-05 17:12:55 -07009111 ENTER();
9112
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 /* Now bind the underlying wlan device with wiphy */
9114 set_wiphy_dev(wiphy, dev);
9115
9116 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009117
Kiet Lam6c583332013-10-14 05:37:09 +05309118#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009119 /* the flag for the other case would be initialzed in
9120 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309121#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9122 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9123#else
Amar Singhal0a402232013-10-11 20:57:16 -07009124 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309125#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309126#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009127
Amar Singhalfddc28c2013-09-05 13:03:40 -07009128 /* This will disable updating of NL channels from passive to
9129 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309130#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9131 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9132#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009133 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309134#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009135
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9137 wiphy->wowlan = &wowlan_support_cfg80211_init;
9138#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309139 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9140 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309141 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9142 wiphy->wowlan.pattern_min_len = 1;
9143 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9144#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009145
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009147 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9148 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9149 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009150 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309152 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309153#else
9154 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9155#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009156#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009157
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009158#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009159 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009160#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009161 || pCfg->isFastRoamIniFeatureEnabled
9162#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009163#ifdef FEATURE_WLAN_ESE
9164 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009165#endif
9166 )
9167 {
9168 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9169 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009170#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009171#ifdef FEATURE_WLAN_TDLS
9172 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9173 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9174#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309175#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309176 if (pCfg->configPNOScanSupport)
9177 {
9178 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9179 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9180 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9181 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9182 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309183#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009184
Abhishek Singh10d85972015-04-17 10:27:23 +05309185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9186 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9187#endif
9188
Amar Singhalfddc28c2013-09-05 13:03:40 -07009189#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009190 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9191 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009192 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009193 driver need to determine what to do with both
9194 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009195
9196 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009197#else
9198 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009199#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009200
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309201 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9202
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309203 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309205 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9206
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309208 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9209 | BIT(NL80211_IFTYPE_ADHOC)
9210 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9211 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309212 | BIT(NL80211_IFTYPE_AP)
9213 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009214
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309215 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009216 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309217#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9218 if( pCfg->enableMCC )
9219 {
9220 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309221 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009222
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309223 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309224 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009225
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309226 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309227 wiphy->iface_combinations = wlan_hdd_iface_combination;
9228 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009229#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309230 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009231
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 /* Before registering we need to update the ht capabilitied based
9233 * on ini values*/
9234 if( !pCfg->ShortGI20MhzEnable )
9235 {
9236 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9237 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 }
9239
9240 if( !pCfg->ShortGI40MhzEnable )
9241 {
9242 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9243 }
9244
9245 if( !pCfg->nChannelBondingMode5GHz )
9246 {
9247 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9248 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309249 /*
9250 * In case of static linked driver at the time of driver unload,
9251 * module exit doesn't happens. Module cleanup helps in cleaning
9252 * of static memory.
9253 * If driver load happens statically, at the time of driver unload,
9254 * wiphy flags don't get reset because of static memory.
9255 * It's better not to store channel in static memory.
9256 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309257 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9258 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309259 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309260 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309261 {
9262 hddLog(VOS_TRACE_LEVEL_ERROR,
9263 FL("Not enough memory to allocate channels"));
9264 return -ENOMEM;
9265 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309266 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309267 &hdd_channels_2_4_GHZ[0],
9268 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009269
Agrawal Ashish97dec502015-11-26 20:20:58 +05309270 if (true == hdd_is_5g_supported(pHddCtx))
9271 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309272 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9273 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309274 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309275 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309276 {
9277 hddLog(VOS_TRACE_LEVEL_ERROR,
9278 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309279 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9280 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309281 return -ENOMEM;
9282 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309283 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309284 &hdd_channels_5_GHZ[0],
9285 sizeof(hdd_channels_5_GHZ));
9286 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309287
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309288 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309289 {
9290
9291 if (NULL == wiphy->bands[i])
9292 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309293 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309294 __func__, i);
9295 continue;
9296 }
9297
9298 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9299 {
9300 struct ieee80211_supported_band *band = wiphy->bands[i];
9301
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309302 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309303 {
9304 // Enable social channels for P2P
9305 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9306 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9307 else
9308 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9309 continue;
9310 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309311 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309312 {
9313 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9314 continue;
9315 }
9316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 }
9318 /*Initialise the supported cipher suite details*/
9319 wiphy->cipher_suites = hdd_cipher_suites;
9320 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9321
9322 /*signal strength in mBm (100*dBm) */
9323 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9324
9325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309326 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009328
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309329 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309330 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9331 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009332 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9333 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9334
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309335 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9336
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309337 EXIT();
9338 return 0;
9339}
9340
9341/* In this function we are registering wiphy. */
9342int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9343{
9344 ENTER();
9345 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 if (0 > wiphy_register(wiphy))
9347 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309348 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9350 return -EIO;
9351 }
9352
9353 EXIT();
9354 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355}
Jeff Johnson295189b2012-06-20 16:38:30 -07009356
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309357/* In this function we are updating channel list when,
9358 regulatory domain is FCC and country code is US.
9359 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9360 As per FCC smart phone is not a indoor device.
9361 GO should not opeate on indoor channels */
9362void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9363{
9364 int j;
9365 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9366 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9367 //Default counrtycode from NV at the time of wiphy initialization.
9368 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9369 &defaultCountryCode[0]))
9370 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009371 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309372 }
9373 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9374 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309375 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309376 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309377 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309378 return;
9379 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309380 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309381 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309382 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309383 // Mark UNII -1 band channel as passive
9384 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9385 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9386 }
9387 }
9388}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309389/* This function registers for all frame which supplicant is interested in */
9390void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009391{
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9393 /* Register for all P2P action, public action etc frames */
9394 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009395 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309396 /* Register frame indication call back */
9397 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 /* Right now we are registering these frame when driver is getting
9399 initialized. Once we will move to 2.6.37 kernel, in which we have
9400 frame register ops, we will move this code as a part of that */
9401 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309402 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9404
9405 /* GAS Initial Response */
9406 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9407 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 /* GAS Comeback Request */
9410 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9411 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9412
9413 /* GAS Comeback Response */
9414 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9415 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9416
9417 /* P2P Public Action */
9418 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 P2P_PUBLIC_ACTION_FRAME_SIZE );
9421
9422 /* P2P Action */
9423 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9424 (v_U8_t*)P2P_ACTION_FRAME,
9425 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009426
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309427 /* WNM BSS Transition Request frame */
9428 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9429 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9430 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009431
9432 /* WNM-Notification */
9433 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9434 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9435 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009436}
9437
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309438void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009439{
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9441 /* Register for all P2P action, public action etc frames */
9442 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9443
Jeff Johnsone7245742012-09-05 17:12:55 -07009444 ENTER();
9445
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 /* Right now we are registering these frame when driver is getting
9447 initialized. Once we will move to 2.6.37 kernel, in which we have
9448 frame register ops, we will move this code as a part of that */
9449 /* GAS Initial Request */
9450
9451 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9452 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9453
9454 /* GAS Initial Response */
9455 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9456 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309457
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 /* GAS Comeback Request */
9459 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9460 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9461
9462 /* GAS Comeback Response */
9463 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9464 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9465
9466 /* P2P Public Action */
9467 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309468 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 P2P_PUBLIC_ACTION_FRAME_SIZE );
9470
9471 /* P2P Action */
9472 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9473 (v_U8_t*)P2P_ACTION_FRAME,
9474 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009475 /* WNM-Notification */
9476 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9477 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9478 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009479}
9480
9481#ifdef FEATURE_WLAN_WAPI
9482void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309483 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009484{
9485 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9486 tCsrRoamSetKey setKey;
9487 v_BOOL_t isConnected = TRUE;
9488 int status = 0;
9489 v_U32_t roamId= 0xFF;
9490 tANI_U8 *pKeyPtr = NULL;
9491 int n = 0;
9492
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309493 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9494 __func__, hdd_device_modetoString(pAdapter->device_mode),
9495 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009496
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309497 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 setKey.keyId = key_index; // Store Key ID
9499 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9500 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9501 setKey.paeRole = 0 ; // the PAE role
9502 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9503 {
9504 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9505 }
9506 else
9507 {
9508 isConnected = hdd_connIsConnected(pHddStaCtx);
9509 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9510 }
9511 setKey.keyLength = key_Len;
9512 pKeyPtr = setKey.Key;
9513 memcpy( pKeyPtr, key, key_Len);
9514
Arif Hussain6d2a3322013-11-17 19:50:10 -08009515 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 __func__, key_Len);
9517 for (n = 0 ; n < key_Len; n++)
9518 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9519 __func__,n,setKey.Key[n]);
9520
9521 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9522 if ( isConnected )
9523 {
9524 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9525 pAdapter->sessionId, &setKey, &roamId );
9526 }
9527 if ( status != 0 )
9528 {
9529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9530 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9531 __LINE__, status );
9532 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9533 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309534 /* Need to clear any trace of key value in the memory.
9535 * Thus zero out the memory even though it is local
9536 * variable.
9537 */
9538 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009539}
9540#endif /* FEATURE_WLAN_WAPI*/
9541
9542#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309543int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 beacon_data_t **ppBeacon,
9545 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009546#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009548 beacon_data_t **ppBeacon,
9549 struct cfg80211_beacon_data *params,
9550 int dtim_period)
9551#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552{
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 int size;
9554 beacon_data_t *beacon = NULL;
9555 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309556 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9557 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Jeff Johnsone7245742012-09-05 17:12:55 -07009559 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309561 {
9562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9563 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009566
9567 old = pAdapter->sessionCtx.ap.beacon;
9568
9569 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309570 {
9571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9572 FL("session(%d) old and new heads points to NULL"),
9573 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309575 }
9576
9577 if (params->tail && !params->tail_len)
9578 {
9579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9580 FL("tail_len is zero but tail is not NULL"));
9581 return -EINVAL;
9582 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009583
Jeff Johnson295189b2012-06-20 16:38:30 -07009584#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9585 /* Kernel 3.0 is not updating dtim_period for set beacon */
9586 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309587 {
9588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9589 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009592#endif
9593
Kapil Gupta137ef892016-12-13 19:38:00 +05309594 if (params->head)
9595 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309597 head = params->head;
9598 } else
9599 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309601 head = old->head;
9602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
Kapil Gupta137ef892016-12-13 19:38:00 +05309604 if (params->tail || !old)
9605 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309607 tail = params->tail;
9608 } else
9609 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309611 tail = old->tail;
9612 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009613
Kapil Gupta137ef892016-12-13 19:38:00 +05309614 if (params->proberesp_ies || !old)
9615 {
9616 proberesp_ies_len = params->proberesp_ies_len;
9617 proberesp_ies = params->proberesp_ies;
9618 } else
9619 {
9620 proberesp_ies_len = old->proberesp_ies_len;
9621 proberesp_ies = old->proberesp_ies;
9622 }
9623
9624 if (params->assocresp_ies || !old)
9625 {
9626 assocresp_ies_len = params->assocresp_ies_len;
9627 assocresp_ies = params->assocresp_ies;
9628 } else
9629 {
9630 assocresp_ies_len = old->assocresp_ies_len;
9631 assocresp_ies = old->assocresp_ies;
9632 }
9633
9634 size = sizeof(beacon_data_t) + head_len + tail_len +
9635 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009636
9637 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309639 {
9640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9641 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309643 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009644
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009645#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309646 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009647 beacon->dtim_period = params->dtim_period;
9648 else
9649 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009650#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309651 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009652 beacon->dtim_period = dtim_period;
9653 else
9654 beacon->dtim_period = old->dtim_period;
9655#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309656
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9658 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 beacon->proberesp_ies = beacon->tail + tail_len;
9660 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 beacon->head_len = head_len;
9663 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309664 beacon->proberesp_ies_len = proberesp_ies_len;
9665 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
c_manjee527ecac2017-01-25 12:25:27 +05309667 if (head && head_len)
9668 memcpy(beacon->head, head, head_len);
9669 if (tail && tail_len)
9670 memcpy(beacon->tail, tail, tail_len);
9671 if (proberesp_ies && proberesp_ies_len)
9672 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9673 if (assocresp_ies && assocresp_ies_len)
9674 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
9676 *ppBeacon = beacon;
9677
9678 kfree(old);
9679
9680 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681}
Jeff Johnson295189b2012-06-20 16:38:30 -07009682
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309683v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9685 const v_U8_t *pIes,
9686#else
9687 v_U8_t *pIes,
9688#endif
9689 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009690{
9691 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309692 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309694
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309696 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 elem_id = ptr[0];
9698 elem_len = ptr[1];
9699 left -= 2;
9700 if(elem_len > left)
9701 {
9702 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009703 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 eid,elem_len,left);
9705 return NULL;
9706 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309707 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 {
9709 return ptr;
9710 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309711
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 left -= elem_len;
9713 ptr += (elem_len + 2);
9714 }
9715 return NULL;
9716}
9717
Jeff Johnson295189b2012-06-20 16:38:30 -07009718/* Check if rate is 11g rate or not */
9719static int wlan_hdd_rate_is_11g(u8 rate)
9720{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009721 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 u8 i;
9723 for (i = 0; i < 8; i++)
9724 {
9725 if(rate == gRateArray[i])
9726 return TRUE;
9727 }
9728 return FALSE;
9729}
9730
9731/* Check for 11g rate and set proper 11g only mode */
9732static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9733 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9734{
9735 u8 i, num_rates = pIe[0];
9736
9737 pIe += 1;
9738 for ( i = 0; i < num_rates; i++)
9739 {
9740 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9741 {
9742 /* If rate set have 11g rate than change the mode to 11G */
9743 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9744 if (pIe[i] & BASIC_RATE_MASK)
9745 {
9746 /* If we have 11g rate as basic rate, it means mode
9747 is 11g only mode.
9748 */
9749 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9750 *pCheckRatesfor11g = FALSE;
9751 }
9752 }
9753 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9754 {
9755 *require_ht = TRUE;
9756 }
9757 }
9758 return;
9759}
9760
9761static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9762{
9763 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9764 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9765 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9766 u8 checkRatesfor11g = TRUE;
9767 u8 require_ht = FALSE;
9768 u8 *pIe=NULL;
9769
9770 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9771
9772 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9773 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9774 if (pIe != NULL)
9775 {
9776 pIe += 1;
9777 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9778 &pConfig->SapHw_mode);
9779 }
9780
9781 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9782 WLAN_EID_EXT_SUPP_RATES);
9783 if (pIe != NULL)
9784 {
9785
9786 pIe += 1;
9787 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9788 &pConfig->SapHw_mode);
9789 }
9790
9791 if( pConfig->channel > 14 )
9792 {
9793 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9794 }
9795
9796 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9797 WLAN_EID_HT_CAPABILITY);
9798
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309799 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 {
9801 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9802 if(require_ht)
9803 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9804 }
9805}
9806
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309807static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9808 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9809{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009810 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309811 v_U8_t *pIe = NULL;
9812 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9813
9814 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9815 pBeacon->tail, pBeacon->tail_len);
9816
9817 if (pIe)
9818 {
9819 ielen = pIe[1] + 2;
9820 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9821 {
9822 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9823 }
9824 else
9825 {
9826 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9827 return -EINVAL;
9828 }
9829 *total_ielen += ielen;
9830 }
9831 return 0;
9832}
9833
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009834static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9835 v_U8_t *genie, v_U8_t *total_ielen)
9836{
9837 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9838 int left = pBeacon->tail_len;
9839 v_U8_t *ptr = pBeacon->tail;
9840 v_U8_t elem_id, elem_len;
9841 v_U16_t ielen = 0;
9842
9843 if ( NULL == ptr || 0 == left )
9844 return;
9845
9846 while (left >= 2)
9847 {
9848 elem_id = ptr[0];
9849 elem_len = ptr[1];
9850 left -= 2;
9851 if (elem_len > left)
9852 {
9853 hddLog( VOS_TRACE_LEVEL_ERROR,
9854 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9855 elem_id, elem_len, left);
9856 return;
9857 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309858 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009859 {
9860 /* skipping the VSIE's which we don't want to include or
9861 * it will be included by existing code
9862 */
9863 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9864#ifdef WLAN_FEATURE_WFD
9865 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9866#endif
9867 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9868 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9869 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9870 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9871 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9872 {
9873 ielen = ptr[1] + 2;
9874 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9875 {
9876 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9877 *total_ielen += ielen;
9878 }
9879 else
9880 {
9881 hddLog( VOS_TRACE_LEVEL_ERROR,
9882 "IE Length is too big "
9883 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9884 elem_id, elem_len, *total_ielen);
9885 }
9886 }
9887 }
9888
9889 left -= elem_len;
9890 ptr += (elem_len + 2);
9891 }
9892 return;
9893}
9894
Kapil Gupta137ef892016-12-13 19:38:00 +05309895int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009896{
9897 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309898 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009900 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309901 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009902
9903 genie = vos_mem_malloc(MAX_GENIE_LEN);
9904
9905 if(genie == NULL) {
9906
9907 return -ENOMEM;
9908 }
9909
Kapil Gupta137ef892016-12-13 19:38:00 +05309910 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309911 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9912 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309914 hddLog(LOGE,
9915 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309916 ret = -EINVAL;
9917 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 }
9919
9920#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309921 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9922 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9923 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309924 hddLog(LOGE,
9925 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309926 ret = -EINVAL;
9927 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 }
9929#endif
9930
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309931 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9932 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309934 hddLog(LOGE,
9935 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309936 ret = -EINVAL;
9937 goto done;
9938 }
9939
9940 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9941 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009942 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009944
9945 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9946 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9947 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9948 {
9949 hddLog(LOGE,
9950 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009951 ret = -EINVAL;
9952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 }
9954
9955 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9956 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9957 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9958 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9959 ==eHAL_STATUS_FAILURE)
9960 {
9961 hddLog(LOGE,
9962 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009963 ret = -EINVAL;
9964 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 }
9966
9967 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309968 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309970 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 u8 probe_rsp_ie_len[3] = {0};
9972 u8 counter = 0;
9973 /* Check Probe Resp Length if it is greater then 255 then Store
9974 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9975 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9976 Store More then 255 bytes into One Variable.
9977 */
9978 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9979 {
9980 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9981 {
9982 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9983 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9984 }
9985 else
9986 {
9987 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9988 rem_probe_resp_ie_len = 0;
9989 }
9990 }
9991
9992 rem_probe_resp_ie_len = 0;
9993
9994 if (probe_rsp_ie_len[0] > 0)
9995 {
9996 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9997 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309998 (tANI_U8*)&pBeacon->
9999 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 probe_rsp_ie_len[0], NULL,
10001 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10002 {
10003 hddLog(LOGE,
10004 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010005 ret = -EINVAL;
10006 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 }
10008 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10009 }
10010
10011 if (probe_rsp_ie_len[1] > 0)
10012 {
10013 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10014 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010015 (tANI_U8*)&pBeacon->
10016 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 probe_rsp_ie_len[1], NULL,
10018 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10019 {
10020 hddLog(LOGE,
10021 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010022 ret = -EINVAL;
10023 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 }
10025 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10026 }
10027
10028 if (probe_rsp_ie_len[2] > 0)
10029 {
10030 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10031 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010032 (tANI_U8*)&pBeacon->
10033 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 probe_rsp_ie_len[2], NULL,
10035 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10036 {
10037 hddLog(LOGE,
10038 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010039 ret = -EINVAL;
10040 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 }
10042 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10043 }
10044
10045 if (probe_rsp_ie_len[1] == 0 )
10046 {
10047 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10048 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10049 eANI_BOOLEAN_FALSE) )
10050 {
10051 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010052 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 }
10054 }
10055
10056 if (probe_rsp_ie_len[2] == 0 )
10057 {
10058 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10059 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10060 eANI_BOOLEAN_FALSE) )
10061 {
10062 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010063 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 }
10065 }
10066
10067 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10068 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10069 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10070 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10071 == eHAL_STATUS_FAILURE)
10072 {
10073 hddLog(LOGE,
10074 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010075 ret = -EINVAL;
10076 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 }
10078 }
10079 else
10080 {
10081 // Reset WNI_CFG_PROBE_RSP Flags
10082 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10083
10084 hddLog(VOS_TRACE_LEVEL_INFO,
10085 "%s: No Probe Response IE received in set beacon",
10086 __func__);
10087 }
10088
10089 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010090 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 {
10092 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010093 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10094 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10096 {
10097 hddLog(LOGE,
10098 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010099 ret = -EINVAL;
10100 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 }
10102
10103 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10104 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10105 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10106 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10107 == eHAL_STATUS_FAILURE)
10108 {
10109 hddLog(LOGE,
10110 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010111 ret = -EINVAL;
10112 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010113 }
10114 }
10115 else
10116 {
10117 hddLog(VOS_TRACE_LEVEL_INFO,
10118 "%s: No Assoc Response IE received in set beacon",
10119 __func__);
10120
10121 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10122 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10123 eANI_BOOLEAN_FALSE) )
10124 {
10125 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 }
10128 }
10129
Jeff Johnsone7245742012-09-05 17:12:55 -070010130done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010132 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133}
Jeff Johnson295189b2012-06-20 16:38:30 -070010134
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010135/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 * FUNCTION: wlan_hdd_validate_operation_channel
10137 * called by wlan_hdd_cfg80211_start_bss() and
10138 * wlan_hdd_cfg80211_set_channel()
10139 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010140 * channel list.
10141 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010142VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010143{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010144
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 v_U32_t num_ch = 0;
10146 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10147 u32 indx = 0;
10148 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010149 v_U8_t fValidChannel = FALSE, count = 0;
10150 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010151
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10153
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010154 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010156 /* Validate the channel */
10157 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010159 if ( channel == rfChannels[count].channelNum )
10160 {
10161 fValidChannel = TRUE;
10162 break;
10163 }
10164 }
10165 if (fValidChannel != TRUE)
10166 {
10167 hddLog(VOS_TRACE_LEVEL_ERROR,
10168 "%s: Invalid Channel [%d]", __func__, channel);
10169 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010170 }
10171 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010172 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010174 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10175 valid_ch, &num_ch))
10176 {
10177 hddLog(VOS_TRACE_LEVEL_ERROR,
10178 "%s: failed to get valid channel list", __func__);
10179 return VOS_STATUS_E_FAILURE;
10180 }
10181 for (indx = 0; indx < num_ch; indx++)
10182 {
10183 if (channel == valid_ch[indx])
10184 {
10185 break;
10186 }
10187 }
10188
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010189 if (indx >= num_ch)
10190 {
10191 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10192 {
10193 eCsrBand band;
10194 unsigned int freq;
10195
10196 sme_GetFreqBand(hHal, &band);
10197
10198 if (eCSR_BAND_5G == band)
10199 {
10200#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10201 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10202 {
10203 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010204 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010205 }
10206 else
10207 {
10208 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010209 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010210 }
10211#else
10212 freq = ieee80211_channel_to_frequency(channel);
10213#endif
10214 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10215 return VOS_STATUS_SUCCESS;
10216 }
10217 }
10218
10219 hddLog(VOS_TRACE_LEVEL_ERROR,
10220 "%s: Invalid Channel [%d]", __func__, channel);
10221 return VOS_STATUS_E_FAILURE;
10222 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010224
Jeff Johnson295189b2012-06-20 16:38:30 -070010225 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010226
Jeff Johnson295189b2012-06-20 16:38:30 -070010227}
10228
Viral Modi3a32cc52013-02-08 11:14:52 -080010229/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010230 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010231 * This function is used to set the channel number
10232 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010233static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010234 struct ieee80211_channel *chan,
10235 enum nl80211_channel_type channel_type
10236 )
10237{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010238 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010239 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010240 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010241 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010242 hdd_context_t *pHddCtx;
10243 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010244
10245 ENTER();
10246
10247 if( NULL == dev )
10248 {
10249 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010250 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010251 return -ENODEV;
10252 }
10253 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010254
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10256 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10257 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010258 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010259 "%s: device_mode = %s (%d) freq = %d", __func__,
10260 hdd_device_modetoString(pAdapter->device_mode),
10261 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010262
10263 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10264 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010265 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010266 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010267 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010268 }
10269
10270 /*
10271 * Do freq to chan conversion
10272 * TODO: for 11a
10273 */
10274
10275 channel = ieee80211_frequency_to_channel(freq);
10276
10277 /* Check freq range */
10278 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10279 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10280 {
10281 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010282 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010283 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10284 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10285 return -EINVAL;
10286 }
10287
10288 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10289
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010290 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10291 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010292 {
10293 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10294 {
10295 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010296 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010297 return -EINVAL;
10298 }
10299 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10300 "%s: set channel to [%d] for device mode =%d",
10301 __func__, channel,pAdapter->device_mode);
10302 }
10303 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010304 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010305 )
10306 {
10307 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10308 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10309 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10310
10311 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10312 {
10313 /* Link is up then return cant set channel*/
10314 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010315 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010316 return -EINVAL;
10317 }
10318
10319 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10320 pHddStaCtx->conn_info.operationChannel = channel;
10321 pRoamProfile->ChannelInfo.ChannelList =
10322 &pHddStaCtx->conn_info.operationChannel;
10323 }
10324 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010325 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010326 )
10327 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010328 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10329 {
10330 if(VOS_STATUS_SUCCESS !=
10331 wlan_hdd_validate_operation_channel(pAdapter,channel))
10332 {
10333 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010334 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010335 return -EINVAL;
10336 }
10337 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10338 }
10339 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010340 {
10341 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10342
10343 /* If auto channel selection is configured as enable/ 1 then ignore
10344 channel set by supplicant
10345 */
10346 if ( cfg_param->apAutoChannelSelection )
10347 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010348 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10349 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010350 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010351 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10352 __func__, hdd_device_modetoString(pAdapter->device_mode),
10353 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010354 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010355 else
10356 {
10357 if(VOS_STATUS_SUCCESS !=
10358 wlan_hdd_validate_operation_channel(pAdapter,channel))
10359 {
10360 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010361 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010362 return -EINVAL;
10363 }
10364 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10365 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010366 }
10367 }
10368 else
10369 {
10370 hddLog(VOS_TRACE_LEVEL_FATAL,
10371 "%s: Invalid device mode failed to set valid channel", __func__);
10372 return -EINVAL;
10373 }
10374 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010375 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010376}
10377
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010378static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10379 struct net_device *dev,
10380 struct ieee80211_channel *chan,
10381 enum nl80211_channel_type channel_type
10382 )
10383{
10384 int ret;
10385
10386 vos_ssr_protect(__func__);
10387 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10388 vos_ssr_unprotect(__func__);
10389
10390 return ret;
10391}
10392
Anurag Chouhan83026002016-12-13 22:46:21 +053010393#ifdef DHCP_SERVER_OFFLOAD
10394void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10395 VOS_STATUS status)
10396{
10397 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10398
10399 ENTER();
10400
10401 if (NULL == adapter)
10402 {
10403 hddLog(VOS_TRACE_LEVEL_ERROR,
10404 "%s: adapter is NULL",__func__);
10405 return;
10406 }
10407
10408 adapter->dhcp_status.dhcp_offload_status = status;
10409 vos_event_set(&adapter->dhcp_status.vos_event);
10410 return;
10411}
10412
10413/**
10414 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10415 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010416 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010417 *
10418 * Return: None
10419 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010420VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10421 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010422{
10423 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10424 sir_dhcp_srv_offload_info dhcp_srv_info;
10425 tANI_U8 num_entries = 0;
10426 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10427 tANI_U8 num;
10428 tANI_U32 temp;
10429 VOS_STATUS ret;
10430
10431 ENTER();
10432
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010433 if (!re_init) {
10434 ret = wlan_hdd_validate_context(hdd_ctx);
10435 if (0 != ret)
10436 return VOS_STATUS_E_INVAL;
10437 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010438
10439 /* Prepare the request to send to SME */
10440 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10441 if (NULL == dhcp_srv_info) {
10442 hddLog(VOS_TRACE_LEVEL_ERROR,
10443 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10444 return VOS_STATUS_E_NOMEM;
10445 }
10446
10447 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10448
10449 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10450 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10451 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10452 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10453 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10454 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10455
10456 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10457 srv_ip,
10458 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010459 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010460 if (num_entries != IPADDR_NUM_ENTRIES) {
10461 hddLog(VOS_TRACE_LEVEL_ERROR,
10462 "%s: incorrect IP address (%s) assigned for DHCP server!",
10463 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10464 vos_mem_free(dhcp_srv_info);
10465 return VOS_STATUS_E_FAILURE;
10466 }
10467
10468 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10469 hddLog(VOS_TRACE_LEVEL_ERROR,
10470 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10471 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10472 vos_mem_free(dhcp_srv_info);
10473 return VOS_STATUS_E_FAILURE;
10474 }
10475
10476 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10477 hddLog(VOS_TRACE_LEVEL_ERROR,
10478 "%s: invalid IP address (%s)! The last field must be less than 100!",
10479 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10480 vos_mem_free(dhcp_srv_info);
10481 return VOS_STATUS_E_FAILURE;
10482 }
10483
10484 for (num = 0; num < num_entries; num++) {
10485 temp = srv_ip[num];
10486 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10487 }
10488
10489 if (eHAL_STATUS_SUCCESS !=
10490 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10491 hddLog(VOS_TRACE_LEVEL_ERROR,
10492 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10493 vos_mem_free(dhcp_srv_info);
10494 return VOS_STATUS_E_FAILURE;
10495 }
10496
10497 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10498 "%s: enable DHCP Server offload successfully!", __func__);
10499
10500 vos_mem_free(dhcp_srv_info);
10501 return 0;
10502}
10503#endif /* DHCP_SERVER_OFFLOAD */
10504
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010505/*
10506 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10507 * @wiphy_chan: wiphy channel number
10508 * @rfChannel: channel hw value
10509 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010510 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010511 *
10512 * Modify wiphy flags and cds state if channel is indoor.
10513 *
10514 * Return: void
10515 */
10516void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010517 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010518{
10519 v_U32_t channelLoop;
10520 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10521
10522 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10523
10524 if (rfChannels[channelLoop].channelNum == rfChannel) {
10525 channelEnum = (eRfChannels)channelLoop;
10526 break;
10527 }
10528 }
10529
10530 if (INVALID_RF_CHANNEL == channelEnum)
10531 return;
10532
10533 if (disable) {
10534 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10535 wiphy_chan->flags |=
10536 IEEE80211_CHAN_DISABLED;
10537 regChannels[channelEnum].enabled =
10538 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010539 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10540 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010541 }
10542 } else {
10543 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10544 wiphy_chan->flags &=
10545 ~IEEE80211_CHAN_DISABLED;
10546 /*
10547 * Indoor channels are marked as DFS
10548 * during regulatory processing
10549 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010550 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10551 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10552 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10553 && (wiphy_chan->flags &
10554 IEEE80211_CHAN_INDOOR_ONLY))) {
10555 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10556 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10557 channelEnum);
10558 } else {
10559 regChannels[channelEnum].enabled =
10560 NV_CHANNEL_ENABLE;
10561 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10562 channelEnum);
10563 }
10564 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010565
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010566 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010567}
10568
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010569void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010570{
10571 int band_num;
10572 int chan_num;
10573 v_U32_t rfChannel;
10574 struct ieee80211_channel *wiphy_chan;
10575 struct wiphy *wiphy;
10576
10577 ENTER();
10578 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10579
10580 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010581 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010582
10583 if (wiphy->bands[band_num] == NULL)
10584 continue;
10585
10586 for (chan_num = 0;
10587 chan_num < wiphy->bands[band_num]->n_channels;
10588 chan_num++) {
10589
10590 wiphy_chan =
10591 &(wiphy->bands[band_num]->channels[chan_num]);
10592 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10593
10594 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010595 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010596 }
10597 }
10598 EXIT();
10599}
10600
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010601int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10602{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010603 eHalStatus status;
10604 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010605 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10606 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10607 long ret;
10608 eConnectionState prev_conn_state;
10609 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10610
10611 ENTER();
10612
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010613 /* Indicate sme of disconnect so that in progress connection or preauth
10614 * can be aborted
10615 */
10616 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10617 pAdapter->sessionId);
10618 pHddCtx->isAmpAllowed = VOS_TRUE;
10619
10620 /* Need to apply spin lock before decreasing active sessions
10621 * as there can be chance for double decrement if context switch
10622 * Calls hdd_DisConnectHandler.
10623 */
10624
10625 prev_conn_state = pHddStaCtx->conn_info.connState;
10626
10627 spin_lock_bh(&pAdapter->lock_for_active_session);
10628 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10629 {
10630 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10631 }
10632 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10633 spin_unlock_bh(&pAdapter->lock_for_active_session);
10634 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10635
10636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10637 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10638
10639 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10640
10641 /*
10642 * stop tx queues before deleting STA/BSS context from the firmware.
10643 * tx has to be disabled because the firmware can get busy dropping
10644 * the tx frames after BSS/STA has been deleted and will not send
10645 * back a response resulting in WDI timeout
10646 */
10647 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10648 netif_tx_disable(pAdapter->dev);
10649 netif_carrier_off(pAdapter->dev);
10650
10651 wlan_hdd_check_and_stop_mon(pAdapter, true);
10652
10653 /*issue disconnect*/
10654 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10655 pAdapter->sessionId, reason);
10656 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10657 prev_conn_state != eConnectionState_Connecting)
10658 {
10659 hddLog(LOG1,
10660 FL("status = %d, already disconnected"), status);
10661 result = 0;
10662 /*
10663 * Wait here instead of returning directly. This will block the
10664 * next connect command and allow processing of the disconnect
10665 * in SME else we might hit some race conditions leading to SME
10666 * and HDD out of sync. As disconnect is already in progress,
10667 * wait here for 1 sec instead of 5 sec.
10668 */
10669 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10670 goto wait_for_disconnect;
10671 }
10672 /*
10673 * Wait here instead of returning directly, this will block the next
10674 * connect command and allow processing of the scan for ssid and
10675 * the previous connect command in CSR. Else we might hit some
10676 * race conditions leading to SME and HDD out of sync.
10677 */
10678 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10679 {
10680 hddLog(LOG1,
10681 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10682 }
10683 else if ( 0 != status )
10684 {
10685 hddLog(LOGE,
10686 FL("csrRoamDisconnect failure, returned %d"),
10687 (int)status);
10688 result = -EINVAL;
10689 goto disconnected;
10690 }
10691wait_for_disconnect:
10692 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10693 msecs_to_jiffies(wait_time));
10694 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10695 {
10696 hddLog(LOGE,
10697 "%s: Failed to disconnect, timed out", __func__);
10698 result = -ETIMEDOUT;
10699 }
10700disconnected:
10701 hddLog(LOG1,
10702 FL("Set HDD connState to eConnectionState_NotConnected"));
10703 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10704#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10705 /* Sending disconnect event to userspace for kernel version < 3.11
10706 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10707 */
10708 hddLog(LOG1, FL("Send disconnected event to userspace"));
10709
10710 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10711 WLAN_REASON_UNSPECIFIED);
10712#endif
10713
10714 EXIT();
10715 return result;
10716}
10717
10718/*
10719 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10720 * on indoor channel
10721 * @hdd_ctx: pointer to hdd context
10722 *
10723 * STA should be disconnected before starting the SAP if it is on indoor
10724 * channel.
10725 *
10726 * Return: void
10727 */
10728void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10729{
10730
10731 hdd_adapter_t *sta_adapter;
10732 tANI_U8 sta_chan;
10733
10734 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10735
10736 if (!sta_chan) {
10737 hddLog(LOG1, FL("STA not connected"));
10738 return;
10739 }
10740
10741 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10742
10743 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10744 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10745 sta_chan);
10746 return;
10747 }
10748
10749 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10750
10751 if (!sta_adapter) {
10752 hddLog(LOG1, FL("STA adapter doesn't exist"));
10753 return;
10754 }
10755
10756 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10757 /* Issue Disconnect request */
10758 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10759}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010760
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010761int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10762{
10763 struct hdd_cache_channels *cache_chann;
10764 struct wiphy *wiphy;
10765 int freq, status, rfChannel;
10766 int i, band_num, channel_num;
10767 struct ieee80211_channel *wiphy_channel;
10768
10769 ENTER();
10770
10771 if (!hdd_ctx) {
10772 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10773 return -EINVAL;
10774 }
10775
10776 wiphy = hdd_ctx->wiphy;
10777
10778 mutex_lock(&hdd_ctx->cache_channel_lock);
10779
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010780 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010781
10782 if (!cache_chann || !cache_chann->num_channels) {
10783 hddLog(VOS_TRACE_LEVEL_INFO,
10784 "%s channel list is NULL or num channels are zero",
10785 __func__);
10786 mutex_unlock(&hdd_ctx->cache_channel_lock);
10787 return -EINVAL;
10788 }
10789
10790 for (i = 0; i < cache_chann->num_channels; i++) {
10791 status = hdd_wlan_get_freq(
10792 cache_chann->channel_info[i].channel_num,
10793 &freq);
10794
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010795 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10796 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010797 if (!wiphy->bands[band_num])
10798 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010799 for (channel_num = 0; channel_num <
10800 wiphy->bands[band_num]->n_channels;
10801 channel_num++) {
10802 wiphy_channel = &(wiphy->bands[band_num]->
10803 channels[channel_num]);
10804 if (wiphy_channel->center_freq == freq) {
10805 rfChannel = wiphy_channel->hw_value;
10806 /*
10807 *Restore the orginal states
10808 *of the channels
10809 */
10810 vos_nv_set_channel_state(
10811 rfChannel,
10812 cache_chann->
10813 channel_info[i].reg_status);
10814 wiphy_channel->flags =
10815 cache_chann->
10816 channel_info[i].wiphy_status;
10817 break;
10818 }
10819 }
10820 if (channel_num < wiphy->bands[band_num]->n_channels)
10821 break;
10822 }
10823 }
10824
10825 mutex_unlock(&hdd_ctx->cache_channel_lock);
10826
10827 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10828 if (status)
10829 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10830 EXIT();
10831
10832 return 0;
10833}
10834
10835/*
10836 * wlan_hdd_disable_channels() - Cache the the channels
10837 * and current state of the channels from the channel list
10838 * received in the command and disable the channels on the
10839 * wiphy and NV table.
10840 * @hdd_ctx: Pointer to hdd context
10841 *
10842 * @return: 0 on success, Error code on failure
10843 */
10844
10845static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10846{
10847 struct hdd_cache_channels *cache_chann;
10848 struct wiphy *wiphy;
10849 int freq, status, rfChannel;
10850 int i, band_num, band_ch_num;
10851 struct ieee80211_channel *wiphy_channel;
10852
10853 if (!hdd_ctx) {
10854 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10855 return -EINVAL;
10856 }
10857
10858 wiphy = hdd_ctx->wiphy;
10859
10860 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010861 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010862
10863 if (!cache_chann || !cache_chann->num_channels) {
10864 hddLog(VOS_TRACE_LEVEL_INFO,
10865 "%s channel list is NULL or num channels are zero",
10866 __func__);
10867 mutex_unlock(&hdd_ctx->cache_channel_lock);
10868 return -EINVAL;
10869 }
10870
10871 for (i = 0; i < cache_chann->num_channels; i++) {
10872 status = hdd_wlan_get_freq(
10873 cache_chann->channel_info[i].channel_num,
10874 &freq);
10875
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010876 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010877 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010878 if (!wiphy->bands[band_num])
10879 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010880 for (band_ch_num = 0; band_ch_num <
10881 wiphy->bands[band_num]->n_channels;
10882 band_ch_num++) {
10883 wiphy_channel = &(wiphy->bands[band_num]->
10884 channels[band_ch_num]);
10885 if (wiphy_channel->center_freq == freq) {
10886 rfChannel = wiphy_channel->hw_value;
10887 /*
10888 * Cache the current states of
10889 * the channels
10890 */
10891 cache_chann->
10892 channel_info[i].reg_status =
10893 vos_nv_getChannelEnabledState(
10894 rfChannel);
10895
10896 cache_chann->
10897 channel_info[i].wiphy_status =
10898 wiphy_channel->flags;
10899 hddLog(VOS_TRACE_LEVEL_INFO,
10900 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10901 cache_chann->
10902 channel_info[i].channel_num,
10903 cache_chann->
10904 channel_info[i].reg_status,
10905 wiphy_channel->flags);
10906
10907 vos_nv_set_channel_state(
10908 rfChannel,
10909 NV_CHANNEL_DISABLE);
10910 wiphy_channel->flags |=
10911 IEEE80211_CHAN_DISABLED;
10912 break;
10913 }
10914 }
10915 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10916 break;
10917 }
10918 }
10919
10920 mutex_unlock(&hdd_ctx->cache_channel_lock);
10921 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10922 return 0;
10923}
10924
Jeff Johnson295189b2012-06-20 16:38:30 -070010925#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10926static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10927 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010928#else
10929static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10930 struct cfg80211_beacon_data *params,
10931 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010932 enum nl80211_hidden_ssid hidden_ssid,
10933 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010935{
10936 tsap_Config_t *pConfig;
10937 beacon_data_t *pBeacon = NULL;
10938 struct ieee80211_mgmt *pMgmt_frame;
10939 v_U8_t *pIe=NULL;
10940 v_U16_t capab_info;
10941 eCsrAuthType RSNAuthType;
10942 eCsrEncryptionType RSNEncryptType;
10943 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010944 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 tpWLAN_SAPEventCB pSapEventCallback;
10946 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010948 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010949 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010950 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010952 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010953 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053010954 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010955 v_BOOL_t MFPCapable = VOS_FALSE;
10956 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010957 v_BOOL_t sapEnable11AC =
10958 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010959 u_int16_t prev_rsn_length = 0;
10960
Jeff Johnson295189b2012-06-20 16:38:30 -070010961 ENTER();
10962
Nitesh Shah9b066282017-06-06 18:05:52 +053010963 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010964
10965 /*
10966 * For STA+SAP concurrency support from GUI, first STA connection gets
10967 * triggered and while it is in progress, SAP start also comes up.
10968 * Once STA association is successful, STA connect event is sent to
10969 * kernel which gets queued in kernel workqueue and supplicant won't
10970 * process M1 received from AP and send M2 until this NL80211_CONNECT
10971 * event is received. Workqueue is not scheduled as RTNL lock is already
10972 * taken by hostapd thread which has issued start_bss command to driver.
10973 * Driver cannot complete start_bss as the pending command at the head
10974 * of the SME command pending list is hw_mode_update for STA session
10975 * which cannot be processed as SME is in WAITforKey state for STA
10976 * interface. The start_bss command for SAP interface is queued behind
10977 * the hw_mode_update command and so it cannot be processed until
10978 * hw_mode_update command is processed. This is causing a deadlock so
10979 * disconnect the STA interface first if connection or key exchange is
10980 * in progress and then start SAP interface.
10981 */
10982 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
10983 if (sta_adapter) {
10984 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
10985 sta_adapter->sessionId);
10986 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10987 }
10988
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010989 iniConfig = pHddCtx->cfg_ini;
10990
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010991 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053010992 if (iniConfig->disable_indoor_channel &&
10993 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010994 hdd_update_indoor_channel(pHddCtx, true);
10995
10996 if (!VOS_IS_STATUS_SUCCESS(
10997 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10998 hdd_update_indoor_channel(pHddCtx, false);
10999 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11000 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011001 ret = eHAL_STATUS_FAILURE;
11002 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011003 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011004
11005 /* check if STA is on indoor channel */
11006 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11007 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011008 }
11009
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011010 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11011 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11012 wlan_hdd_disable_channels(pHddCtx);
11013 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11014 }
11015
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11017
11018 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11019
11020 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11021
11022 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11023
11024 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11025
11026 //channel is already set in the set_channel Call back
11027 //pConfig->channel = pCommitConfig->channel;
11028
11029 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011030 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011031 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11032
11033 pConfig->dtim_period = pBeacon->dtim_period;
11034
Arif Hussain6d2a3322013-11-17 19:50:10 -080011035 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 pConfig->dtim_period);
11037
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011038 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011039 {
11040 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011042 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11043 {
11044 tANI_BOOLEAN restartNeeded;
11045 pConfig->ieee80211d = 1;
11046 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11047 sme_setRegInfo(hHal, pConfig->countryCode);
11048 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11049 }
11050 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011052 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011053 pConfig->ieee80211d = 1;
11054 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11055 sme_setRegInfo(hHal, pConfig->countryCode);
11056 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011058 else
11059 {
11060 pConfig->ieee80211d = 0;
11061 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011062 /*
11063 * If auto channel is configured i.e. channel is 0,
11064 * so skip channel validation.
11065 */
11066 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11067 {
11068 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11069 {
11070 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011071 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011072 ret = -EINVAL;
11073 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011074 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011075 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011076 }
11077 else
11078 {
11079 if(1 != pHddCtx->is_dynamic_channel_range_set)
11080 {
11081 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11082 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11083 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11084 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011085 pHddCtx->is_dynamic_channel_range_set = 0;
11086 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011087 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011088 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011089 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 {
11091 pConfig->ieee80211d = 0;
11092 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011093
11094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11095 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11096 pConfig->authType = eSAP_OPEN_SYSTEM;
11097 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11098 pConfig->authType = eSAP_SHARED_KEY;
11099 else
11100 pConfig->authType = eSAP_AUTO_SWITCH;
11101#else
11102 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11103 pConfig->authType = eSAP_OPEN_SYSTEM;
11104 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11105 pConfig->authType = eSAP_SHARED_KEY;
11106 else
11107 pConfig->authType = eSAP_AUTO_SWITCH;
11108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011109
11110 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011111
11112 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011114#ifdef SAP_AUTH_OFFLOAD
11115 /* In case of sap offload, hostapd.conf is configuted with open mode and
11116 * security is configured from ini file. Due to open mode in hostapd.conf
11117 * privacy bit is set to false which will result in not sending,
11118 * data packets as encrypted.
11119 * If enable_sap_auth_offload is enabled in ini and
11120 * sap_auth_offload_sec_type is type of WPA2-PSK,
11121 * driver will set privacy bit to 1.
11122 */
11123 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11124 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11125 pConfig->privacy = VOS_TRUE;
11126#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011127
11128 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11129
11130 /*Set wps station to configured*/
11131 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11132
11133 if(pIe)
11134 {
11135 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11136 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011137 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011138 ret = -EINVAL;
11139 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011140 }
11141 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11142 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011143 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 /* Check 15 bit of WPS IE as it contain information for wps state
11145 * WPS state
11146 */
11147 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11148 {
11149 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11150 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11151 {
11152 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11153 }
11154 }
11155 }
11156 else
11157 {
11158 pConfig->wps_state = SAP_WPS_DISABLED;
11159 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011161
c_hpothufe599e92014-06-16 11:38:55 +053011162 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11163 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11164 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11165 eCSR_ENCRYPT_TYPE_NONE;
11166
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011168 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 WLAN_EID_RSN);
11171 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011174 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11175 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11176 pConfig->RSNWPAReqIELength);
11177 else
11178 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11179 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011180 /* The actual processing may eventually be more extensive than
11181 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 * by the app.
11183 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011184 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11186 &RSNEncryptType,
11187 &mcRSNEncryptType,
11188 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011189 &MFPCapable,
11190 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011191 pConfig->RSNWPAReqIE[1]+2,
11192 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011193
11194 if( VOS_STATUS_SUCCESS == status )
11195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011196 /* Now copy over all the security attributes you have
11197 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011198 * */
11199 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11200 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11201 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11202 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011203 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011204 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11206 }
11207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011208
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11210 pBeacon->tail, pBeacon->tail_len);
11211
11212 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11213 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011214 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 {
11216 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011217 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011219 if (pConfig->RSNWPAReqIELength <=
11220 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11221 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11222 pIe[1] + 2);
11223 else
11224 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11225 pConfig->RSNWPAReqIELength);
11226
Jeff Johnson295189b2012-06-20 16:38:30 -070011227 }
11228 else
11229 {
11230 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011231 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11232 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11233 pConfig->RSNWPAReqIELength);
11234 else
11235 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11236 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011237 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11239 &RSNEncryptType,
11240 &mcRSNEncryptType,
11241 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011242 &MFPCapable,
11243 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011244 pConfig->RSNWPAReqIE[1]+2,
11245 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011246
11247 if( VOS_STATUS_SUCCESS == status )
11248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011249 /* Now copy over all the security attributes you have
11250 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 * */
11252 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11253 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11254 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11255 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011256 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011257 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11259 }
11260 }
11261 }
11262
Kapil Gupta137ef892016-12-13 19:38:00 +053011263 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011264 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011265 ret = -EINVAL;
11266 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011267 }
11268
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11270
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011271#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 if (params->ssid != NULL)
11273 {
11274 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11275 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11276 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11277 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11278 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011279#else
11280 if (ssid != NULL)
11281 {
11282 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11283 pConfig->SSIDinfo.ssid.length = ssid_len;
11284 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11285 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11286 }
11287#endif
11288
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011289 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011291
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 /* default value */
11293 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11294 pConfig->num_accept_mac = 0;
11295 pConfig->num_deny_mac = 0;
11296
11297 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11298 pBeacon->tail, pBeacon->tail_len);
11299
11300 /* pIe for black list is following form:
11301 type : 1 byte
11302 length : 1 byte
11303 OUI : 4 bytes
11304 acl type : 1 byte
11305 no of mac addr in black list: 1 byte
11306 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011307 */
11308 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 {
11310 pConfig->SapMacaddr_acl = pIe[6];
11311 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011312 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011313 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011314 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11315 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11317 for (i = 0; i < pConfig->num_deny_mac; i++)
11318 {
11319 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11320 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 }
11323 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11324 pBeacon->tail, pBeacon->tail_len);
11325
11326 /* pIe for white list is following form:
11327 type : 1 byte
11328 length : 1 byte
11329 OUI : 4 bytes
11330 acl type : 1 byte
11331 no of mac addr in white list: 1 byte
11332 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011333 */
11334 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 {
11336 pConfig->SapMacaddr_acl = pIe[6];
11337 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011338 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011340 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11341 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11343 for (i = 0; i < pConfig->num_accept_mac; i++)
11344 {
11345 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11346 acl_entry++;
11347 }
11348 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011349
Jeff Johnson295189b2012-06-20 16:38:30 -070011350 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11351
Jeff Johnsone7245742012-09-05 17:12:55 -070011352#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011353 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011354 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11355 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011356 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11357 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011358 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11359 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011360 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11361 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011362 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011363 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011364 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011365 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011366
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011367 /* If ACS disable and selected channel <= 14
11368 * OR
11369 * ACS enabled and ACS operating band is choosen as 2.4
11370 * AND
11371 * VHT in 2.4G Disabled
11372 * THEN
11373 * Fallback to 11N mode
11374 */
11375 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11376 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011377 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011378 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011379 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011380 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11381 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011382 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11383 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011384 }
11385#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011386
Jeff Johnson295189b2012-06-20 16:38:30 -070011387 // ht_capab is not what the name conveys,this is used for protection bitmap
11388 pConfig->ht_capab =
11389 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11390
Kapil Gupta137ef892016-12-13 19:38:00 +053011391 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011392 {
11393 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011394 ret = -EINVAL;
11395 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011396 }
11397
11398 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11401 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011402 pConfig->obssProtEnabled =
11403 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011404
Chet Lanctot8cecea22014-02-11 19:09:36 -080011405#ifdef WLAN_FEATURE_11W
11406 pConfig->mfpCapable = MFPCapable;
11407 pConfig->mfpRequired = MFPRequired;
11408 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11409 pConfig->mfpCapable, pConfig->mfpRequired);
11410#endif
11411
Arif Hussain6d2a3322013-11-17 19:50:10 -080011412 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011414 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11415 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11416 (int)pConfig->channel);
11417 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11418 pConfig->SapHw_mode, pConfig->privacy,
11419 pConfig->authType);
11420 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11421 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11422 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11423 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011424
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011425 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 {
11427 //Bss already started. just return.
11428 //TODO Probably it should update some beacon params.
11429 hddLog( LOGE, "Bss Already started...Ignore the request");
11430 EXIT();
11431 return 0;
11432 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011433
Agarwal Ashish51325b52014-06-16 16:50:49 +053011434 if (vos_max_concurrent_connections_reached()) {
11435 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011436 ret = -EINVAL;
11437 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011438 }
11439
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 pConfig->persona = pHostapdAdapter->device_mode;
11441
Peng Xu2446a892014-09-05 17:21:18 +053011442 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11443 if ( NULL != psmeConfig)
11444 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011445 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011446 sme_GetConfigParam(hHal, psmeConfig);
11447 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011448#ifdef WLAN_FEATURE_AP_HT40_24G
11449 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11450 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11451 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11452 {
11453 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11454 sme_UpdateConfig (hHal, psmeConfig);
11455 }
11456#endif
Peng Xu2446a892014-09-05 17:21:18 +053011457 vos_mem_free(psmeConfig);
11458 }
Peng Xuafc34e32014-09-25 13:23:55 +053011459 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011460
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011461 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011463
11464 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11466 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11467 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011468 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011469 ret = -EINVAL;
11470 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 }
11472
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11475
11476 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011479 {
11480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011481 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011482 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 VOS_ASSERT(0);
11484 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011487 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11488 VOS_STATUS_SUCCESS)
11489 {
11490 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11491 VOS_ASSERT(0);
11492 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011493 /* Initialize WMM configuation */
11494 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011495 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011496
Anurag Chouhan83026002016-12-13 22:46:21 +053011497#ifdef DHCP_SERVER_OFFLOAD
11498 /* set dhcp server offload */
11499 if (iniConfig->enable_dhcp_srv_offload &&
11500 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011501 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011502 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011503 if (!VOS_IS_STATUS_SUCCESS(status))
11504 {
11505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11506 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011507 vos_event_reset(&pHostapdState->vosEvent);
11508 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11509 status = vos_wait_single_event(&pHostapdState->vosEvent,
11510 10000);
11511 if (!VOS_IS_STATUS_SUCCESS(status)) {
11512 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011513 ret = -EINVAL;
11514 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011515 }
11516 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011517 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011518 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11519 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11520 {
11521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11522 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11523 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011524 vos_event_reset(&pHostapdState->vosEvent);
11525 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11526 status = vos_wait_single_event(&pHostapdState->vosEvent,
11527 10000);
11528 if (!VOS_IS_STATUS_SUCCESS(status)) {
11529 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011530 ret = -EINVAL;
11531 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011532 }
11533 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011534 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011535#ifdef MDNS_OFFLOAD
11536 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011537 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011538 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11539 if (VOS_IS_STATUS_SUCCESS(status))
11540 {
11541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11542 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011543 vos_event_reset(&pHostapdState->vosEvent);
11544 if (VOS_STATUS_SUCCESS ==
11545 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11546 status = vos_wait_single_event(&pHostapdState->vosEvent,
11547 10000);
11548 if (!VOS_IS_STATUS_SUCCESS(status)) {
11549 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011550 ret = -EINVAL;
11551 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011552 }
11553 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011554 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011555 status = vos_wait_single_event(&pHostapdAdapter->
11556 mdns_status.vos_event, 2000);
11557 if (!VOS_IS_STATUS_SUCCESS(status) ||
11558 pHostapdAdapter->mdns_status.mdns_enable_status ||
11559 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11560 pHostapdAdapter->mdns_status.mdns_resp_status)
11561 {
11562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11563 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11564 pHostapdAdapter->mdns_status.mdns_enable_status,
11565 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11566 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011567 vos_event_reset(&pHostapdState->vosEvent);
11568 if (VOS_STATUS_SUCCESS ==
11569 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11570 status = vos_wait_single_event(&pHostapdState->vosEvent,
11571 10000);
11572 if (!VOS_IS_STATUS_SUCCESS(status)) {
11573 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011574 ret = -EINVAL;
11575 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011576 }
11577 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011578 }
11579 }
11580#endif /* MDNS_OFFLOAD */
11581 } else {
11582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11583 ("DHCP Disabled ini %d, FW %d"),
11584 iniConfig->enable_dhcp_srv_offload,
11585 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011586 }
11587#endif /* DHCP_SERVER_OFFLOAD */
11588
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011589#ifdef WLAN_FEATURE_P2P_DEBUG
11590 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11591 {
11592 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11593 {
11594 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11595 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011596 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011597 }
11598 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11599 {
11600 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11601 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011602 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011603 }
11604 }
11605#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011606 /* Check and restart SAP if it is on Unsafe channel */
11607 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011608
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 pHostapdState->bCommit = TRUE;
11610 EXIT();
11611
11612 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011613error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011614 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11615 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011616 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011617 if (iniConfig->disable_indoor_channel &&
11618 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011619 hdd_update_indoor_channel(pHddCtx, false);
11620 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11621 }
11622
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011623 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011624
11625tdls_enable:
11626 if (ret != eHAL_STATUS_SUCCESS)
11627 wlan_hdd_tdls_reenable(pHddCtx);
11628
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011629 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011630}
11631
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011632#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011633static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011634 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 struct beacon_parameters *params)
11636{
11637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011638 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011639 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011640
11641 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011642
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11644 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11645 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011646 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11647 hdd_device_modetoString(pAdapter->device_mode),
11648 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011649
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011650 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11651 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011652 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011653 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011654 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011655 }
11656
Agarwal Ashish51325b52014-06-16 16:50:49 +053011657 if (vos_max_concurrent_connections_reached()) {
11658 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11659 return -EINVAL;
11660 }
11661
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011662 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 )
11665 {
11666 beacon_data_t *old,*new;
11667
11668 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011669
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011671 {
11672 hddLog(VOS_TRACE_LEVEL_WARN,
11673 FL("already beacon info added to session(%d)"),
11674 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011677
11678 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11679
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011680 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 {
11682 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011683 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 return -EINVAL;
11685 }
11686
11687 pAdapter->sessionCtx.ap.beacon = new;
11688
11689 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11690 }
11691
11692 EXIT();
11693 return status;
11694}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011696static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11697 struct net_device *dev,
11698 struct beacon_parameters *params)
11699{
11700 int ret;
11701
11702 vos_ssr_protect(__func__);
11703 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11704 vos_ssr_unprotect(__func__);
11705
11706 return ret;
11707}
11708
11709static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 struct net_device *dev,
11711 struct beacon_parameters *params)
11712{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011713 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011714 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11715 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011716 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011717
11718 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011719
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011720 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11721 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11722 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11724 __func__, hdd_device_modetoString(pAdapter->device_mode),
11725 pAdapter->device_mode);
11726
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11728 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011729 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011730 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011731 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011732 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011733
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011734 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 {
11738 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011739
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011741
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011743 {
11744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11745 FL("session(%d) old and new heads points to NULL"),
11746 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011748 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011749
11750 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11751
11752 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011754 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 return -EINVAL;
11756 }
11757
11758 pAdapter->sessionCtx.ap.beacon = new;
11759
11760 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11761 }
11762
11763 EXIT();
11764 return status;
11765}
11766
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011767static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11768 struct net_device *dev,
11769 struct beacon_parameters *params)
11770{
11771 int ret;
11772
11773 vos_ssr_protect(__func__);
11774 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11775 vos_ssr_unprotect(__func__);
11776
11777 return ret;
11778}
11779
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011780#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11781
11782#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011783static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011785#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011786static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011787 struct net_device *dev)
11788#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011789{
11790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011791 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011792 hdd_context_t *pHddCtx = NULL;
11793 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011795 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011796
11797 ENTER();
11798
11799 if (NULL == pAdapter)
11800 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011802 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 return -ENODEV;
11804 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11807 TRACE_CODE_HDD_CFG80211_STOP_AP,
11808 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11810 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011811 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011812 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011813 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011814 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011815
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011816 pScanInfo = &pHddCtx->scan_info;
11817
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11819 __func__, hdd_device_modetoString(pAdapter->device_mode),
11820 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011821
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011822 /*
11823 * if a sta connection is in progress in another adapter, disconnect
11824 * the sta and complete the sap operation. sta will reconnect
11825 * after sap stop is done.
11826 */
11827 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11828 if (staAdapter) {
11829 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11830 staAdapter->sessionId);
11831 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11832 }
11833
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011834 ret = wlan_hdd_scan_abort(pAdapter);
11835
Girish Gowli4bf7a632014-06-12 13:42:11 +053011836 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011837 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11839 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011840
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011841 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011842 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11844 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011845
Jeff Johnsone7245742012-09-05 17:12:55 -070011846 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011847 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011848 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011849 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011850 }
11851
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011852 /* Delete all associated STAs before stopping AP/P2P GO */
11853 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011854 hdd_hostapd_stop(dev);
11855
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011857 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 )
11859 {
11860 beacon_data_t *old;
11861
11862 old = pAdapter->sessionCtx.ap.beacon;
11863
11864 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011865 {
11866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11867 FL("session(%d) beacon data points to NULL"),
11868 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011869 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011870 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011871
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011873
11874 mutex_lock(&pHddCtx->sap_lock);
11875 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11876 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011877 hdd_hostapd_state_t *pHostapdState =
11878 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11879
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011880 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11881 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011882 vos_event_reset(&pHostapdState->vosEvent);
11883
Jeff Johnson4416a782013-03-25 14:17:50 -070011884 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11887
11888 if (!VOS_IS_STATUS_SUCCESS(status))
11889 {
11890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011891 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011893 }
11894 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011895 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011896 /* BSS stopped, clear the active sessions for this device mode */
11897 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 }
11899 mutex_unlock(&pHddCtx->sap_lock);
11900
11901 if(status != VOS_STATUS_SUCCESS)
11902 {
11903 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011904 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011905 return -EINVAL;
11906 }
11907
Jeff Johnson4416a782013-03-25 14:17:50 -070011908 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11910 ==eHAL_STATUS_FAILURE)
11911 {
11912 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011913 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011914 }
11915
Jeff Johnson4416a782013-03-25 14:17:50 -070011916 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011917 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11918 eANI_BOOLEAN_FALSE) )
11919 {
11920 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011921 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 }
11923
11924 // Reset WNI_CFG_PROBE_RSP Flags
11925 wlan_hdd_reset_prob_rspies(pAdapter);
11926
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011927 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11928
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 pAdapter->sessionCtx.ap.beacon = NULL;
11930 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011931#ifdef WLAN_FEATURE_P2P_DEBUG
11932 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11933 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11934 {
11935 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11936 "GO got removed");
11937 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11938 }
11939#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 }
11941 EXIT();
11942 return status;
11943}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011944
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011945#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11946static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11947 struct net_device *dev)
11948{
11949 int ret;
11950
11951 vos_ssr_protect(__func__);
11952 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11953 vos_ssr_unprotect(__func__);
11954
11955 return ret;
11956}
11957#else
11958static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11959 struct net_device *dev)
11960{
11961 int ret;
11962
11963 vos_ssr_protect(__func__);
11964 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11965 vos_ssr_unprotect(__func__);
11966
11967 return ret;
11968}
11969#endif
11970
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011971#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11972
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011973static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011974 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011975 struct cfg80211_ap_settings *params)
11976{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011977 hdd_adapter_t *pAdapter;
11978 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011979 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011980
11981 ENTER();
11982
Girish Gowlib143d7a2015-02-18 19:39:55 +053011983 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011986 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011987 return -ENODEV;
11988 }
11989
11990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11991 if (NULL == pAdapter)
11992 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011994 "%s: HDD adapter is Null", __func__);
11995 return -ENODEV;
11996 }
11997
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11999 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12000 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012001 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12002 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012004 "%s: HDD adapter magic is invalid", __func__);
12005 return -ENODEV;
12006 }
12007
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012008 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12009
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012010 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012011 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012012 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012013 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012014 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012015 }
12016
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012017 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12018 __func__, hdd_device_modetoString(pAdapter->device_mode),
12019 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012020
12021 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012022 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012023 )
12024 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012025 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012026
12027 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012028
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012029 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012030 {
12031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12032 FL("already beacon info added to session(%d)"),
12033 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012035 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012036
Girish Gowlib143d7a2015-02-18 19:39:55 +053012037#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12038 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12039 &new,
12040 &params->beacon);
12041#else
12042 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12043 &new,
12044 &params->beacon,
12045 params->dtim_period);
12046#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012047
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012048 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012049 {
12050 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012051 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012052 return -EINVAL;
12053 }
12054 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012056 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12057#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12058 params->channel, params->channel_type);
12059#else
12060 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12061#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012062#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012063 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012064 params->ssid_len, params->hidden_ssid,
12065 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012066 }
12067
12068 EXIT();
12069 return status;
12070}
12071
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012072static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12073 struct net_device *dev,
12074 struct cfg80211_ap_settings *params)
12075{
12076 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012077
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012078 vos_ssr_protect(__func__);
12079 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12080 vos_ssr_unprotect(__func__);
12081
12082 return ret;
12083}
12084
12085static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012086 struct net_device *dev,
12087 struct cfg80211_beacon_data *params)
12088{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012089 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012090 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012091 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012092
12093 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12096 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12097 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012099 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012100
12101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12102 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012103 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012105 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012106 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012107
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012108 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012109 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012110 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012111 {
12112 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012113
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012114 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012117 {
12118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12119 FL("session(%d) beacon data points to NULL"),
12120 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012121 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012122 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012123
12124 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12125
12126 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012127 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012128 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012129 return -EINVAL;
12130 }
12131
12132 pAdapter->sessionCtx.ap.beacon = new;
12133
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012134 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12135 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012136 }
12137
12138 EXIT();
12139 return status;
12140}
12141
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012142static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12143 struct net_device *dev,
12144 struct cfg80211_beacon_data *params)
12145{
12146 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012147
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012148 vos_ssr_protect(__func__);
12149 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12150 vos_ssr_unprotect(__func__);
12151
12152 return ret;
12153}
12154
12155#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012156
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012157static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 struct net_device *dev,
12159 struct bss_parameters *params)
12160{
12161 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012162 hdd_context_t *pHddCtx;
12163 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012164
12165 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012166
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012167 if (NULL == pAdapter)
12168 {
12169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12170 "%s: HDD adapter is Null", __func__);
12171 return -ENODEV;
12172 }
12173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012174 ret = wlan_hdd_validate_context(pHddCtx);
12175 if (0 != ret)
12176 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012177 return ret;
12178 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12180 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12181 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12183 __func__, hdd_device_modetoString(pAdapter->device_mode),
12184 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012185
12186 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 {
12190 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12191 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012192 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 {
12194 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012195 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 }
12197
12198 EXIT();
12199 return 0;
12200}
12201
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012202static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12203 struct net_device *dev,
12204 struct bss_parameters *params)
12205{
12206 int ret;
12207
12208 vos_ssr_protect(__func__);
12209 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12210 vos_ssr_unprotect(__func__);
12211
12212 return ret;
12213}
Kiet Lam10841362013-11-01 11:36:50 +053012214/* FUNCTION: wlan_hdd_change_country_code_cd
12215* to wait for contry code completion
12216*/
12217void* wlan_hdd_change_country_code_cb(void *pAdapter)
12218{
12219 hdd_adapter_t *call_back_pAdapter = pAdapter;
12220 complete(&call_back_pAdapter->change_country_code);
12221 return NULL;
12222}
12223
Jeff Johnson295189b2012-06-20 16:38:30 -070012224/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012225 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012226 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12227 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012228int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 struct net_device *ndev,
12230 enum nl80211_iftype type,
12231 u32 *flags,
12232 struct vif_params *params
12233 )
12234{
12235 struct wireless_dev *wdev;
12236 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012237 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012238 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012239 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012241 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 eMib_dot11DesiredBssType connectedBssType;
12243 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012244 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012245
12246 ENTER();
12247
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012248 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012249 {
12250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12251 "%s: Adapter context is null", __func__);
12252 return VOS_STATUS_E_FAILURE;
12253 }
12254
12255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12256 if (!pHddCtx)
12257 {
12258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12259 "%s: HDD context is null", __func__);
12260 return VOS_STATUS_E_FAILURE;
12261 }
12262
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12264 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12265 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012266 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012267 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012269 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 }
12271
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012272 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12273 __func__, hdd_device_modetoString(pAdapter->device_mode),
12274 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012275
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012276 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12277 hddLog(VOS_TRACE_LEVEL_FATAL,
12278 "%s: STA + MON is in progress, cannot change interface",
12279 __func__);
12280 }
12281
Agarwal Ashish51325b52014-06-16 16:50:49 +053012282 if (vos_max_concurrent_connections_reached()) {
12283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12284 return -EINVAL;
12285 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012286 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012287 wdev = ndev->ieee80211_ptr;
12288
12289#ifdef WLAN_BTAMP_FEATURE
12290 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12291 (NL80211_IFTYPE_ADHOC == type)||
12292 (NL80211_IFTYPE_AP == type)||
12293 (NL80211_IFTYPE_P2P_GO == type))
12294 {
12295 pHddCtx->isAmpAllowed = VOS_FALSE;
12296 // stop AMP traffic
12297 status = WLANBAP_StopAmp();
12298 if(VOS_STATUS_SUCCESS != status )
12299 {
12300 pHddCtx->isAmpAllowed = VOS_TRUE;
12301 hddLog(VOS_TRACE_LEVEL_FATAL,
12302 "%s: Failed to stop AMP", __func__);
12303 return -EINVAL;
12304 }
12305 }
12306#endif //WLAN_BTAMP_FEATURE
12307 /* Reset the current device mode bit mask*/
12308 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12309
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012310 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12311 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12312 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012313 {
12314 /* Notify Mode change in case of concurrency.
12315 * Below function invokes TDLS teardown Functionality Since TDLS is
12316 * not Supported in case of concurrency i.e Once P2P session
12317 * is detected disable offchannel and teardown TDLS links
12318 */
12319 hddLog(LOG1,
12320 FL("Device mode = %d Interface type = %d"),
12321 pAdapter->device_mode, type);
12322 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12323 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012324
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012327 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 )
12329 {
12330 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012331 if (!pWextState)
12332 {
12333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12334 "%s: pWextState is null", __func__);
12335 return VOS_STATUS_E_FAILURE;
12336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 pRoamProfile = &pWextState->roamProfile;
12338 LastBSSType = pRoamProfile->BSSType;
12339
12340 switch (type)
12341 {
12342 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012343 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 hddLog(VOS_TRACE_LEVEL_INFO,
12345 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12346 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012347#ifdef WLAN_FEATURE_11AC
12348 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12349 {
12350 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12351 }
12352#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012353 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012354 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012356 //Check for sub-string p2p to confirm its a p2p interface
12357 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012358 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012359#ifdef FEATURE_WLAN_TDLS
12360 mutex_lock(&pHddCtx->tdls_lock);
12361 wlan_hdd_tdls_exit(pAdapter, TRUE);
12362 mutex_unlock(&pHddCtx->tdls_lock);
12363#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012364 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12365 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12366 }
12367 else
12368 {
12369 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012370 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012371 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012373
Jeff Johnson295189b2012-06-20 16:38:30 -070012374 case NL80211_IFTYPE_ADHOC:
12375 hddLog(VOS_TRACE_LEVEL_INFO,
12376 "%s: setting interface Type to ADHOC", __func__);
12377 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12378 pRoamProfile->phyMode =
12379 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012380 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012382 hdd_set_ibss_ops( pAdapter );
12383 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012384
12385 status = hdd_sta_id_hash_attach(pAdapter);
12386 if (VOS_STATUS_SUCCESS != status) {
12387 hddLog(VOS_TRACE_LEVEL_ERROR,
12388 FL("Failed to initialize hash for IBSS"));
12389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 break;
12391
12392 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 {
12395 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12396 "%s: setting interface Type to %s", __func__,
12397 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12398
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012399 //Cancel any remain on channel for GO mode
12400 if (NL80211_IFTYPE_P2P_GO == type)
12401 {
12402 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12403 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012404 if (NL80211_IFTYPE_AP == type)
12405 {
12406 /*
12407 * As Loading WLAN Driver one interface being created
12408 * for p2p device address. This will take one HW STA and
12409 * the max number of clients that can connect to softAP
12410 * will be reduced by one. so while changing the interface
12411 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12412 * as it is not required in SoftAP mode.
12413 */
12414
12415 // Get P2P Adapter
12416 pP2pAdapter = hdd_get_adapter(pHddCtx,
12417 WLAN_HDD_P2P_DEVICE);
12418 if (pP2pAdapter)
12419 {
12420 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12421 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12422 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12423 }
12424 }
12425
Swaroop Goltia2e32212014-04-09 23:37:33 +053012426 //Disable IMPS & BMPS for SAP/GO
12427 if(VOS_STATUS_E_FAILURE ==
12428 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12429 {
12430 //Fail to Exit BMPS
12431 VOS_ASSERT(0);
12432 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012433
12434 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12435
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012436#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012437
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012438 /* A Mutex Lock is introduced while changing the mode to
12439 * protect the concurrent access for the Adapters by TDLS
12440 * module.
12441 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012442 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012445 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012447 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12448 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012449#ifdef FEATURE_WLAN_TDLS
12450 mutex_unlock(&pHddCtx->tdls_lock);
12451#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012452 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12453 (pConfig->apRandomBssidEnabled))
12454 {
12455 /* To meet Android requirements create a randomized
12456 MAC address of the form 02:1A:11:Fx:xx:xx */
12457 get_random_bytes(&ndev->dev_addr[3], 3);
12458 ndev->dev_addr[0] = 0x02;
12459 ndev->dev_addr[1] = 0x1A;
12460 ndev->dev_addr[2] = 0x11;
12461 ndev->dev_addr[3] |= 0xF0;
12462 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12463 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012464 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12465 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012466 }
12467
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 hdd_set_ap_ops( pAdapter->dev );
12469
Kiet Lam10841362013-11-01 11:36:50 +053012470 /* This is for only SAP mode where users can
12471 * control country through ini.
12472 * P2P GO follows station country code
12473 * acquired during the STA scanning. */
12474 if((NL80211_IFTYPE_AP == type) &&
12475 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12476 {
12477 int status = 0;
12478 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12479 "%s: setting country code from INI ", __func__);
12480 init_completion(&pAdapter->change_country_code);
12481 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12482 (void *)(tSmeChangeCountryCallback)
12483 wlan_hdd_change_country_code_cb,
12484 pConfig->apCntryCode, pAdapter,
12485 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012486 eSIR_FALSE,
12487 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012488 if (eHAL_STATUS_SUCCESS == status)
12489 {
12490 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012491 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012492 &pAdapter->change_country_code,
12493 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012494 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012495 {
12496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012497 FL("SME Timed out while setting country code %ld"),
12498 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012499
12500 if (pHddCtx->isLogpInProgress)
12501 {
12502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12503 "%s: LOGP in Progress. Ignore!!!", __func__);
12504 return -EAGAIN;
12505 }
Kiet Lam10841362013-11-01 11:36:50 +053012506 }
12507 }
12508 else
12509 {
12510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012511 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012512 return -EINVAL;
12513 }
12514 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012515 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 if(status != VOS_STATUS_SUCCESS)
12517 {
12518 hddLog(VOS_TRACE_LEVEL_FATAL,
12519 "%s: Error initializing the ap mode", __func__);
12520 return -EINVAL;
12521 }
12522 hdd_set_conparam(1);
12523
Nirav Shah7e3c8132015-06-22 23:51:42 +053012524 status = hdd_sta_id_hash_attach(pAdapter);
12525 if (VOS_STATUS_SUCCESS != status)
12526 {
12527 hddLog(VOS_TRACE_LEVEL_ERROR,
12528 FL("Failed to initialize hash for AP"));
12529 return -EINVAL;
12530 }
12531
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 /*interface type changed update in wiphy structure*/
12533 if(wdev)
12534 {
12535 wdev->iftype = type;
12536 pHddCtx->change_iface = type;
12537 }
12538 else
12539 {
12540 hddLog(VOS_TRACE_LEVEL_ERROR,
12541 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12542 return -EINVAL;
12543 }
12544 goto done;
12545 }
12546
12547 default:
12548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12549 __func__);
12550 return -EOPNOTSUPP;
12551 }
12552 }
12553 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 )
12556 {
12557 switch(type)
12558 {
12559 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012562
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012563 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12564 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12565 /*
12566 * The p2p interface was deleted while SoftAP mode was init,
12567 * create that interface now that the SoftAP is going down.
12568 */
12569 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12570 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12571 VOS_TRUE);
12572 }
12573
Deepthi Gowri500fc472014-08-11 19:53:10 +053012574 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012575
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012576#ifdef FEATURE_WLAN_TDLS
12577
12578 /* A Mutex Lock is introduced while changing the mode to
12579 * protect the concurrent access for the Adapters by TDLS
12580 * module.
12581 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012582 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012583#endif
c_hpothu002231a2015-02-05 14:58:51 +053012584 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012586 //Check for sub-string p2p to confirm its a p2p interface
12587 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012588 {
12589 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12590 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12591 }
12592 else
12593 {
12594 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012596 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012597
12598 /* set con_mode to STA only when no SAP concurrency mode */
12599 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12600 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12603 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012604#ifdef FEATURE_WLAN_TDLS
12605 mutex_unlock(&pHddCtx->tdls_lock);
12606#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012607 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 if( VOS_STATUS_SUCCESS != status )
12609 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012610 /* In case of JB, for P2P-GO, only change interface will be called,
12611 * This is the right place to enable back bmps_imps()
12612 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012613 if (pHddCtx->hdd_wlan_suspended)
12614 {
12615 hdd_set_pwrparams(pHddCtx);
12616 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012617 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 goto done;
12619 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012620 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12623 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 goto done;
12625 default:
12626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12627 __func__);
12628 return -EOPNOTSUPP;
12629
12630 }
12631
12632 }
12633 else
12634 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012635 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12636 __func__, hdd_device_modetoString(pAdapter->device_mode),
12637 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 return -EOPNOTSUPP;
12639 }
12640
12641
12642 if(pRoamProfile)
12643 {
12644 if ( LastBSSType != pRoamProfile->BSSType )
12645 {
12646 /*interface type changed update in wiphy structure*/
12647 wdev->iftype = type;
12648
12649 /*the BSS mode changed, We need to issue disconnect
12650 if connected or in IBSS disconnect state*/
12651 if ( hdd_connGetConnectedBssType(
12652 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12653 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12654 {
12655 /*need to issue a disconnect to CSR.*/
12656 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12657 if( eHAL_STATUS_SUCCESS ==
12658 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12659 pAdapter->sessionId,
12660 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12661 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012662 ret = wait_for_completion_interruptible_timeout(
12663 &pAdapter->disconnect_comp_var,
12664 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12665 if (ret <= 0)
12666 {
12667 hddLog(VOS_TRACE_LEVEL_ERROR,
12668 FL("wait on disconnect_comp_var failed %ld"), ret);
12669 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012670 }
12671 }
12672 }
12673 }
12674
12675done:
12676 /*set bitmask based on updated value*/
12677 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012678
12679 /* Only STA mode support TM now
12680 * all other mode, TM feature should be disabled */
12681 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12682 (~VOS_STA & pHddCtx->concurrency_mode) )
12683 {
12684 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12685 }
12686
Jeff Johnson295189b2012-06-20 16:38:30 -070012687#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012688 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012689 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012690 {
12691 //we are ok to do AMP
12692 pHddCtx->isAmpAllowed = VOS_TRUE;
12693 }
12694#endif //WLAN_BTAMP_FEATURE
12695 EXIT();
12696 return 0;
12697}
12698
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012699/*
12700 * FUNCTION: wlan_hdd_cfg80211_change_iface
12701 * wrapper function to protect the actual implementation from SSR.
12702 */
12703int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12704 struct net_device *ndev,
12705 enum nl80211_iftype type,
12706 u32 *flags,
12707 struct vif_params *params
12708 )
12709{
12710 int ret;
12711
12712 vos_ssr_protect(__func__);
12713 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12714 vos_ssr_unprotect(__func__);
12715
12716 return ret;
12717}
12718
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012719#ifdef FEATURE_WLAN_TDLS
12720static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012721 struct net_device *dev,
12722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12723 const u8 *mac,
12724#else
12725 u8 *mac,
12726#endif
12727 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012728{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012729 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012730 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012731 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012732 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012733 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012734 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012735
12736 ENTER();
12737
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012738 if (!dev) {
12739 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12740 return -EINVAL;
12741 }
12742
12743 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12744 if (!pAdapter) {
12745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12746 return -EINVAL;
12747 }
12748
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012749 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012750 {
12751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12752 "Invalid arguments");
12753 return -EINVAL;
12754 }
Hoonki Lee27511902013-03-14 18:19:06 -070012755
12756 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12757 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12758 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012760 "%s: TDLS mode is disabled OR not enabled in FW."
12761 MAC_ADDRESS_STR " Request declined.",
12762 __func__, MAC_ADDR_ARRAY(mac));
12763 return -ENOTSUPP;
12764 }
12765
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012766 if (pHddCtx->isLogpInProgress)
12767 {
12768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12769 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012770 wlan_hdd_tdls_set_link_status(pAdapter,
12771 mac,
12772 eTDLS_LINK_IDLE,
12773 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012774 return -EBUSY;
12775 }
12776
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012777 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012778 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012779
12780 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012782 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12783 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012784 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012785 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012786 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012787
12788 /* in add station, we accept existing valid staId if there is */
12789 if ((0 == update) &&
12790 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12791 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012792 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012794 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012795 " link_status %d. staId %d. add station ignored.",
12796 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012797 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012798 return 0;
12799 }
12800 /* in change station, we accept only when staId is valid */
12801 if ((1 == update) &&
12802 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12803 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12804 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012805 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012807 "%s: " MAC_ADDRESS_STR
12808 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012809 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12810 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12811 mutex_unlock(&pHddCtx->tdls_lock);
12812 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012813 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012814 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012815
12816 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012817 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012818 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12820 "%s: " MAC_ADDRESS_STR
12821 " TDLS setup is ongoing. Request declined.",
12822 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012823 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012824 }
12825
12826 /* first to check if we reached to maximum supported TDLS peer.
12827 TODO: for now, return -EPERM looks working fine,
12828 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012829 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12830 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012831 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12833 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012834 " TDLS Max peer already connected. Request declined."
12835 " Num of peers (%d), Max allowed (%d).",
12836 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12837 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012838 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012839 }
12840 else
12841 {
12842 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012843 mutex_lock(&pHddCtx->tdls_lock);
12844 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012845 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012846 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012847 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12849 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12850 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012851 return -EPERM;
12852 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012853 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012854 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012855 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012856 wlan_hdd_tdls_set_link_status(pAdapter,
12857 mac,
12858 eTDLS_LINK_CONNECTING,
12859 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012860
Jeff Johnsond75fe012013-04-06 10:53:06 -070012861 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012862 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012863 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012865 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012866 if(StaParams->htcap_present)
12867 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012869 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012871 "ht_capa->extended_capabilities: %0x",
12872 StaParams->HTCap.extendedHtCapInfo);
12873 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012875 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012877 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012878 if(StaParams->vhtcap_present)
12879 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012881 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12882 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12883 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12884 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012885 {
12886 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012888 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012890 "[%d]: %x ", i, StaParams->supported_rates[i]);
12891 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012892 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012893 else if ((1 == update) && (NULL == StaParams))
12894 {
12895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12896 "%s : update is true, but staParams is NULL. Error!", __func__);
12897 return -EPERM;
12898 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012899
12900 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12901
12902 if (!update)
12903 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012904 /*Before adding sta make sure that device exited from BMPS*/
12905 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12906 {
12907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12908 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12909 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12910 if (status != VOS_STATUS_SUCCESS) {
12911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12912 }
12913 }
12914
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012915 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012916 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012917 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012918 hddLog(VOS_TRACE_LEVEL_ERROR,
12919 FL("Failed to add TDLS peer STA. Enable Bmps"));
12920 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012921 return -EPERM;
12922 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012923 }
12924 else
12925 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012926 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012927 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012928 if (ret != eHAL_STATUS_SUCCESS) {
12929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12930 return -EPERM;
12931 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012932 }
12933
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012934 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012935 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12936
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012937 mutex_lock(&pHddCtx->tdls_lock);
12938 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12939
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012940 if ((pTdlsPeer != NULL) &&
12941 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012942 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012943 hddLog(VOS_TRACE_LEVEL_ERROR,
12944 FL("peer link status %u"), pTdlsPeer->link_status);
12945 mutex_unlock(&pHddCtx->tdls_lock);
12946 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012947 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012948 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012949
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012950 if (ret <= 0)
12951 {
12952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12953 "%s: timeout waiting for tdls add station indication %ld",
12954 __func__, ret);
12955 goto error;
12956 }
12957
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012958 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12959 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012961 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012962 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012963 }
12964
12965 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012966
12967error:
Atul Mittal115287b2014-07-08 13:26:33 +053012968 wlan_hdd_tdls_set_link_status(pAdapter,
12969 mac,
12970 eTDLS_LINK_IDLE,
12971 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012972 return -EPERM;
12973
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012974}
12975#endif
12976
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012977VOS_STATUS wlan_hdd_send_sta_authorized_event(
12978 hdd_adapter_t *adapter,
12979 hdd_context_t *hdd_ctx,
12980 const v_MACADDR_t *mac_addr)
12981{
12982 struct sk_buff *vendor_event;
12983 uint32_t sta_flags = 0;
12984 VOS_STATUS status;
12985
12986 ENTER();
12987
12988 if (!hdd_ctx) {
12989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12990 return -EINVAL;
12991 }
12992
12993 vendor_event =
12994 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053012995 hdd_ctx->wiphy,
12996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12997 &adapter->wdev,
12998#endif
12999 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013000 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13001 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13002 GFP_KERNEL);
13003 if (!vendor_event) {
13004 hddLog(VOS_TRACE_LEVEL_ERROR,
13005 FL("cfg80211_vendor_event_alloc failed"));
13006 return -EINVAL;
13007 }
13008
13009 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13010
13011 status = nla_put_u32(vendor_event,
13012 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13013 sta_flags);
13014 if (status) {
13015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13016 kfree_skb(vendor_event);
13017 return VOS_STATUS_E_FAILURE;
13018 }
13019 status = nla_put(vendor_event,
13020 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13021 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13022 if (status) {
13023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13024 kfree_skb(vendor_event);
13025 return VOS_STATUS_E_FAILURE;
13026 }
13027
13028 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13029
13030 EXIT();
13031 return 0;
13032}
13033
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013034static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13037 const u8 *mac,
13038#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013040#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 struct station_parameters *params)
13042{
13043 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013044 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013045 hdd_context_t *pHddCtx;
13046 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013047 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013048 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013049#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013050 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013051 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013052 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013053 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013054#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013055
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013056 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013057
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013058 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013059 if ((NULL == pAdapter))
13060 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013062 "invalid adapter ");
13063 return -EINVAL;
13064 }
13065
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013066 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13067 TRACE_CODE_HDD_CHANGE_STATION,
13068 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013069 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013070
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013071 ret = wlan_hdd_validate_context(pHddCtx);
13072 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013073 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013074 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013075 }
13076
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013077 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13078
13079 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013080 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13082 "invalid HDD station context");
13083 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013084 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13086
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013087 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13088 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013089 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013090 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013092 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 WLANTL_STA_AUTHENTICATED);
13094
Gopichand Nakkala29149562013-05-10 21:43:41 +053013095 if (status != VOS_STATUS_SUCCESS)
13096 {
13097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13098 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13099 return -EINVAL;
13100 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013101 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13102 &STAMacAddress);
13103 if (status != VOS_STATUS_SUCCESS)
13104 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 }
13106 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013107 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13108 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013109#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013110 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13111 StaParams.capability = params->capability;
13112 StaParams.uapsd_queues = params->uapsd_queues;
13113 StaParams.max_sp = params->max_sp;
13114
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013115 /* Convert (first channel , number of channels) tuple to
13116 * the total list of channels. This goes with the assumption
13117 * that if the first channel is < 14, then the next channels
13118 * are an incremental of 1 else an incremental of 4 till the number
13119 * of channels.
13120 */
13121 if (0 != params->supported_channels_len) {
13122 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013123 for ( i = 0 ; i < params->supported_channels_len
13124 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013125 {
13126 int wifi_chan_index;
13127 StaParams.supported_channels[j] = params->supported_channels[i];
13128 wifi_chan_index =
13129 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13130 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013131 for(k=1; k <= no_of_channels
13132 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013133 {
13134 StaParams.supported_channels[j+1] =
13135 StaParams.supported_channels[j] + wifi_chan_index;
13136 j+=1;
13137 }
13138 }
13139 StaParams.supported_channels_len = j;
13140 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013141 if (params->supported_oper_classes_len >
13142 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13144 "received oper classes:%d, resetting it to max supported %d",
13145 params->supported_oper_classes_len,
13146 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13147 params->supported_oper_classes_len =
13148 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13149 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013150 vos_mem_copy(StaParams.supported_oper_classes,
13151 params->supported_oper_classes,
13152 params->supported_oper_classes_len);
13153 StaParams.supported_oper_classes_len =
13154 params->supported_oper_classes_len;
13155
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013156 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13158 "received extn capabilities:%d, resetting it to max supported",
13159 params->ext_capab_len);
13160 params->ext_capab_len = sizeof(StaParams.extn_capability);
13161 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013162 if (0 != params->ext_capab_len)
13163 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013164 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013165
13166 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013167 {
13168 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013169 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013170 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013171
13172 StaParams.supported_rates_len = params->supported_rates_len;
13173
13174 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13175 * The supported_rates array , for all the structures propogating till Add Sta
13176 * to the firmware has to be modified , if the supplicant (ieee80211) is
13177 * modified to send more rates.
13178 */
13179
13180 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13181 */
13182 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13183 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13184
13185 if (0 != StaParams.supported_rates_len) {
13186 int i = 0;
13187 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13188 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013190 "Supported Rates with Length %d", StaParams.supported_rates_len);
13191 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013193 "[%d]: %0x", i, StaParams.supported_rates[i]);
13194 }
13195
13196 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013197 {
13198 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013199 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013200 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013201
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013202 if (0 != params->ext_capab_len ) {
13203 /*Define A Macro : TODO Sunil*/
13204 if ((1<<4) & StaParams.extn_capability[3]) {
13205 isBufSta = 1;
13206 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013207 /* TDLS Channel Switching Support */
13208 if ((1<<6) & StaParams.extn_capability[3]) {
13209 isOffChannelSupported = 1;
13210 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013211 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013212
13213 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013214 (params->ht_capa || params->vht_capa ||
13215 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013216 /* TDLS Peer is WME/QoS capable */
13217 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013218
13219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13220 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13221 __func__, isQosWmmSta, StaParams.htcap_present);
13222
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013223 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13224 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013225 isOffChannelSupported,
13226 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013227
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013228 if (VOS_STATUS_SUCCESS != status) {
13229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13230 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13231 return -EINVAL;
13232 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013233 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13234
13235 if (VOS_STATUS_SUCCESS != status) {
13236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13237 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13238 return -EINVAL;
13239 }
13240 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013241#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013242 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013243 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 return status;
13245}
13246
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013247#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13248static int wlan_hdd_change_station(struct wiphy *wiphy,
13249 struct net_device *dev,
13250 const u8 *mac,
13251 struct station_parameters *params)
13252#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013253static int wlan_hdd_change_station(struct wiphy *wiphy,
13254 struct net_device *dev,
13255 u8 *mac,
13256 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013257#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013258{
13259 int ret;
13260
13261 vos_ssr_protect(__func__);
13262 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13263 vos_ssr_unprotect(__func__);
13264
13265 return ret;
13266}
13267
Jeff Johnson295189b2012-06-20 16:38:30 -070013268/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013269 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 * This function is used to initialize the key information
13271 */
13272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013273static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013274 struct net_device *ndev,
13275 u8 key_index, bool pairwise,
13276 const u8 *mac_addr,
13277 struct key_params *params
13278 )
13279#else
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, const u8 *mac_addr,
13283 struct key_params *params
13284 )
13285#endif
13286{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013287 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013288 tCsrRoamSetKey setKey;
13289 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013290 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013291 v_U32_t roamId= 0xFF;
13292 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013293 hdd_hostapd_state_t *pHostapdState;
13294 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013295 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013296 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013297 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013298 v_MACADDR_t *peerMacAddr;
13299 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013300 uint8_t staid = HDD_MAX_STA_COUNT;
13301 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013302
13303 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013304
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013305 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13306 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13307 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13309 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013310 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013311 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013312 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013313 }
13314
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013315 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13316 __func__, hdd_device_modetoString(pAdapter->device_mode),
13317 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013318
13319 if (CSR_MAX_NUM_KEY <= key_index)
13320 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 key_index);
13323
13324 return -EINVAL;
13325 }
13326
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013327 if (CSR_MAX_KEY_LEN < params->key_len)
13328 {
13329 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13330 params->key_len);
13331
13332 return -EINVAL;
13333 }
13334
Jingxiang Gec438aea2017-10-26 16:44:00 +080013335 if (CSR_MAX_RSC_LEN < params->seq_len)
13336 {
13337 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13338 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013339
13340 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013341 }
13342
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013343 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013344 "%s: called with key index = %d & key length %d & seq length %d",
13345 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013346
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013347 peerMacAddr = (v_MACADDR_t *)mac_addr;
13348
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 /*extract key idx, key len and key*/
13350 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13351 setKey.keyId = key_index;
13352 setKey.keyLength = params->key_len;
13353 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013354 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013355
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013356 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 {
13358 case WLAN_CIPHER_SUITE_WEP40:
13359 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13360 break;
13361
13362 case WLAN_CIPHER_SUITE_WEP104:
13363 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13364 break;
13365
13366 case WLAN_CIPHER_SUITE_TKIP:
13367 {
13368 u8 *pKey = &setKey.Key[0];
13369 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13370
13371 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13372
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013373 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013374
13375 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013376 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 |--------------|----------|----------|
13378 <---16bytes---><--8bytes--><--8bytes-->
13379
13380 */
13381 /*Sme expects the 32 bytes key to be in the below order
13382
13383 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013384 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 |--------------|----------|----------|
13386 <---16bytes---><--8bytes--><--8bytes-->
13387 */
13388 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013389 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013390
13391 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013392 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013393
13394 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013395 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013396
13397
13398 break;
13399 }
13400
13401 case WLAN_CIPHER_SUITE_CCMP:
13402 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13403 break;
13404
13405#ifdef FEATURE_WLAN_WAPI
13406 case WLAN_CIPHER_SUITE_SMS4:
13407 {
13408 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13409 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13410 params->key, params->key_len);
13411 return 0;
13412 }
13413#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013414
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013415#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 case WLAN_CIPHER_SUITE_KRK:
13417 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13418 break;
13419#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013420
13421#ifdef WLAN_FEATURE_11W
13422 case WLAN_CIPHER_SUITE_AES_CMAC:
13423 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013424 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013425#endif
13426
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013429 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013430 status = -EOPNOTSUPP;
13431 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013432 }
13433
13434 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13435 __func__, setKey.encType);
13436
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013437 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013438#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13439 (!pairwise)
13440#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013441 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013442#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013443 )
13444 {
13445 /* set group key*/
13446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13447 "%s- %d: setting Broadcast key",
13448 __func__, __LINE__);
13449 setKey.keyDirection = eSIR_RX_ONLY;
13450 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13451 }
13452 else
13453 {
13454 /* set pairwise key*/
13455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13456 "%s- %d: setting pairwise key",
13457 __func__, __LINE__);
13458 setKey.keyDirection = eSIR_TX_RX;
13459 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013460 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013461 }
13462 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13463 {
13464 setKey.keyDirection = eSIR_TX_RX;
13465 /*Set the group key*/
13466 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13467 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013468
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013469 if ( 0 != status )
13470 {
13471 hddLog(VOS_TRACE_LEVEL_ERROR,
13472 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013473 status = -EINVAL;
13474 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013475 }
13476 /*Save the keys here and call sme_RoamSetKey for setting
13477 the PTK after peer joins the IBSS network*/
13478 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13479 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013480 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013481 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013482 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13483 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13484 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013485 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013486 if( pHostapdState->bssState == BSS_START )
13487 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13489 vos_status = wlan_hdd_check_ula_done(pAdapter);
13490
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013491 if (peerMacAddr && (pairwise_set_key == true))
13492 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013493
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013494 if ( vos_status != VOS_STATUS_SUCCESS )
13495 {
13496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13497 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13498 __LINE__, vos_status );
13499
13500 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13501
13502 status = -EINVAL;
13503 goto end;
13504 }
13505
Jeff Johnson295189b2012-06-20 16:38:30 -070013506 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13507
13508 if ( status != eHAL_STATUS_SUCCESS )
13509 {
13510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13511 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13512 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013513 status = -EINVAL;
13514 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 }
13516 }
13517
13518 /* Saving WEP keys */
13519 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13520 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13521 {
13522 //Save the wep key in ap context. Issue setkey after the BSS is started.
13523 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13524 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13525 }
13526 else
13527 {
13528 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013529 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013530 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13531 }
13532 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013533 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13534 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013535 {
13536 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13537 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13538
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13540 if (!pairwise)
13541#else
13542 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13543#endif
13544 {
13545 /* set group key*/
13546 if (pHddStaCtx->roam_info.deferKeyComplete)
13547 {
13548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13549 "%s- %d: Perform Set key Complete",
13550 __func__, __LINE__);
13551 hdd_PerformRoamSetKeyComplete(pAdapter);
13552 }
13553 }
13554
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013555 if (pairwise_set_key == true)
13556 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013557
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13559
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013560 pWextState->roamProfile.Keys.defaultIndex = key_index;
13561
13562
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013563 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013564 params->key, params->key_len);
13565
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013566
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13568
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013569 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013571 __func__, setKey.peerMac[0], setKey.peerMac[1],
13572 setKey.peerMac[2], setKey.peerMac[3],
13573 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 setKey.keyDirection);
13575
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013576 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013577
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013578 if ( vos_status != VOS_STATUS_SUCCESS )
13579 {
13580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13582 __LINE__, vos_status );
13583
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013584 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013585
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013586 status = -EINVAL;
13587 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013588
13589 }
13590
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013591#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013592 /* The supplicant may attempt to set the PTK once pre-authentication
13593 is done. Save the key in the UMAC and include it in the ADD BSS
13594 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013595 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013596 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013597 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013598 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13599 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013600 status = 0;
13601 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013602 }
13603 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13604 {
13605 hddLog(VOS_TRACE_LEVEL_ERROR,
13606 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013607 status = -EINVAL;
13608 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013609 }
13610#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013611
13612 /* issue set key request to SME*/
13613 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13614 pAdapter->sessionId, &setKey, &roamId );
13615
13616 if ( 0 != status )
13617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013618 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013619 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13620 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013621 status = -EINVAL;
13622 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 }
13624
13625
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013626 /* in case of IBSS as there was no information available about WEP keys during
13627 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013629 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13630 !( ( IW_AUTH_KEY_MGMT_802_1X
13631 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13633 )
13634 &&
13635 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13636 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13637 )
13638 )
13639 {
13640 setKey.keyDirection = eSIR_RX_ONLY;
13641 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13642
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645 __func__, setKey.peerMac[0], setKey.peerMac[1],
13646 setKey.peerMac[2], setKey.peerMac[3],
13647 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 setKey.keyDirection);
13649
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013650 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 pAdapter->sessionId, &setKey, &roamId );
13652
13653 if ( 0 != status )
13654 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013655 hddLog(VOS_TRACE_LEVEL_ERROR,
13656 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 __func__, status);
13658 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013659 status = -EINVAL;
13660 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 }
13662 }
13663 }
13664
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013665 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013666 for (i = 0; i < params->seq_len; i++) {
13667 rsc_counter |= (params->seq[i] << i*8);
13668 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013669 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13670 }
13671
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013672end:
13673 /* Need to clear any trace of key value in the memory.
13674 * Thus zero out the memory even though it is local
13675 * variable.
13676 */
13677 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013678 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013679 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013680}
13681
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013682#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13683static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13684 struct net_device *ndev,
13685 u8 key_index, bool pairwise,
13686 const u8 *mac_addr,
13687 struct key_params *params
13688 )
13689#else
13690static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13691 struct net_device *ndev,
13692 u8 key_index, const u8 *mac_addr,
13693 struct key_params *params
13694 )
13695#endif
13696{
13697 int ret;
13698 vos_ssr_protect(__func__);
13699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13700 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13701 mac_addr, params);
13702#else
13703 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13704 params);
13705#endif
13706 vos_ssr_unprotect(__func__);
13707
13708 return ret;
13709}
13710
Jeff Johnson295189b2012-06-20 16:38:30 -070013711/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013712 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013713 * This function is used to get the key information
13714 */
13715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013716static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013717 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013718 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 const u8 *mac_addr, void *cookie,
13721 void (*callback)(void *cookie, struct key_params*)
13722 )
13723#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013724static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013725 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 struct net_device *ndev,
13727 u8 key_index, const u8 *mac_addr, void *cookie,
13728 void (*callback)(void *cookie, struct key_params*)
13729 )
13730#endif
13731{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013733 hdd_wext_state_t *pWextState = NULL;
13734 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013736 hdd_context_t *pHddCtx;
13737 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013738
13739 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013740
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013741 if (NULL == pAdapter)
13742 {
13743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13744 "%s: HDD adapter is Null", __func__);
13745 return -ENODEV;
13746 }
13747
13748 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13749 ret = wlan_hdd_validate_context(pHddCtx);
13750 if (0 != ret)
13751 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013752 return ret;
13753 }
13754
13755 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13756 pRoamProfile = &(pWextState->roamProfile);
13757
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13759 __func__, hdd_device_modetoString(pAdapter->device_mode),
13760 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013761
Jeff Johnson295189b2012-06-20 16:38:30 -070013762 memset(&params, 0, sizeof(params));
13763
13764 if (CSR_MAX_NUM_KEY <= key_index)
13765 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013768 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013769
13770 switch(pRoamProfile->EncryptionType.encryptionType[0])
13771 {
13772 case eCSR_ENCRYPT_TYPE_NONE:
13773 params.cipher = IW_AUTH_CIPHER_NONE;
13774 break;
13775
13776 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13777 case eCSR_ENCRYPT_TYPE_WEP40:
13778 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13779 break;
13780
13781 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13782 case eCSR_ENCRYPT_TYPE_WEP104:
13783 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13784 break;
13785
13786 case eCSR_ENCRYPT_TYPE_TKIP:
13787 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13788 break;
13789
13790 case eCSR_ENCRYPT_TYPE_AES:
13791 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13792 break;
13793
13794 default:
13795 params.cipher = IW_AUTH_CIPHER_NONE;
13796 break;
13797 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013798
c_hpothuaaf19692014-05-17 17:01:48 +053013799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13800 TRACE_CODE_HDD_CFG80211_GET_KEY,
13801 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013802
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13804 params.seq_len = 0;
13805 params.seq = NULL;
13806 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13807 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013808 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 return 0;
13810}
13811
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13813static int wlan_hdd_cfg80211_get_key(
13814 struct wiphy *wiphy,
13815 struct net_device *ndev,
13816 u8 key_index, bool pairwise,
13817 const u8 *mac_addr, void *cookie,
13818 void (*callback)(void *cookie, struct key_params*)
13819 )
13820#else
13821static int wlan_hdd_cfg80211_get_key(
13822 struct wiphy *wiphy,
13823 struct net_device *ndev,
13824 u8 key_index, const u8 *mac_addr, void *cookie,
13825 void (*callback)(void *cookie, struct key_params*)
13826 )
13827#endif
13828{
13829 int ret;
13830
13831 vos_ssr_protect(__func__);
13832#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13833 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13834 mac_addr, cookie, callback);
13835#else
13836 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13837 callback);
13838#endif
13839 vos_ssr_unprotect(__func__);
13840
13841 return ret;
13842}
13843
Jeff Johnson295189b2012-06-20 16:38:30 -070013844/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013845 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 * This function is used to delete the key information
13847 */
13848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013849static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013851 u8 key_index,
13852 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 const u8 *mac_addr
13854 )
13855#else
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,
13858 u8 key_index,
13859 const u8 *mac_addr
13860 )
13861#endif
13862{
13863 int status = 0;
13864
13865 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 //it is observed that this is invalidating peer
13868 //key index whenever re-key is done. This is affecting data link.
13869 //It should be ok to ignore del_key.
13870#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13872 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13874 tCsrRoamSetKey setKey;
13875 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013876
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 ENTER();
13878
13879 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13880 __func__,pAdapter->device_mode);
13881
13882 if (CSR_MAX_NUM_KEY <= key_index)
13883 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013885 key_index);
13886
13887 return -EINVAL;
13888 }
13889
13890 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13891 setKey.keyId = key_index;
13892
13893 if (mac_addr)
13894 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13895 else
13896 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13897
13898 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13899
13900 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013902 )
13903 {
13904
13905 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13907 if( pHostapdState->bssState == BSS_START)
13908 {
13909 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013910
Jeff Johnson295189b2012-06-20 16:38:30 -070013911 if ( status != eHAL_STATUS_SUCCESS )
13912 {
13913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13914 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13915 __LINE__, status );
13916 }
13917 }
13918 }
13919 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 )
13922 {
13923 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13924
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013925 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13926
13927 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013929 __func__, setKey.peerMac[0], setKey.peerMac[1],
13930 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013932 if(pAdapter->sessionCtx.station.conn_info.connState ==
13933 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013934 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013937
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 if ( 0 != status )
13939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013940 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 "%s: sme_RoamSetKey failure, returned %d",
13942 __func__, status);
13943 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13944 return -EINVAL;
13945 }
13946 }
13947 }
13948#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013949 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013950 return status;
13951}
13952
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013953#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13954static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13955 struct net_device *ndev,
13956 u8 key_index,
13957 bool pairwise,
13958 const u8 *mac_addr
13959 )
13960#else
13961static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13962 struct net_device *ndev,
13963 u8 key_index,
13964 const u8 *mac_addr
13965 )
13966#endif
13967{
13968 int ret;
13969
13970 vos_ssr_protect(__func__);
13971#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13972 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13973 mac_addr);
13974#else
13975 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13976#endif
13977 vos_ssr_unprotect(__func__);
13978
13979 return ret;
13980}
13981
Jeff Johnson295189b2012-06-20 16:38:30 -070013982/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013983 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013984 * This function is used to set the default tx key index
13985 */
13986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013987static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 struct net_device *ndev,
13989 u8 key_index,
13990 bool unicast, bool multicast)
13991#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013992static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013993 struct net_device *ndev,
13994 u8 key_index)
13995#endif
13996{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013997 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013998 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013999 hdd_wext_state_t *pWextState;
14000 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014001 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014002
14003 ENTER();
14004
Gopichand Nakkala29149562013-05-10 21:43:41 +053014005 if ((NULL == pAdapter))
14006 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014008 "invalid adapter");
14009 return -EINVAL;
14010 }
14011
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014012 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14013 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14014 pAdapter->sessionId, key_index));
14015
Gopichand Nakkala29149562013-05-10 21:43:41 +053014016 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14017 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14018
14019 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14020 {
14021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14022 "invalid Wext state or HDD context");
14023 return -EINVAL;
14024 }
14025
Arif Hussain6d2a3322013-11-17 19:50:10 -080014026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014027 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014028
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 if (CSR_MAX_NUM_KEY <= key_index)
14030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014032 key_index);
14033
14034 return -EINVAL;
14035 }
14036
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014037 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14038 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014039 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014040 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014041 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014042 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014043
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014045 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014046 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014048 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014049 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014050#ifdef FEATURE_WLAN_WAPI
14051 (eCSR_ENCRYPT_TYPE_WPI !=
14052 pHddStaCtx->conn_info.ucEncryptionType) &&
14053#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014054 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014055 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014056 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057 {
14058 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 tCsrRoamSetKey setKey;
14062 v_U32_t roamId= 0xFF;
14063 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014064
14065 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014067
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 Keys->defaultIndex = (u8)key_index;
14069 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14070 setKey.keyId = key_index;
14071 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072
14073 vos_mem_copy(&setKey.Key[0],
14074 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014076
Gopichand Nakkala29149562013-05-10 21:43:41 +053014077 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014078
14079 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014080 &pHddStaCtx->conn_info.bssId[0],
14081 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014082
Gopichand Nakkala29149562013-05-10 21:43:41 +053014083 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14084 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14085 eCSR_ENCRYPT_TYPE_WEP104)
14086 {
14087 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14088 even though ap is configured for WEP-40 encryption. In this canse the key length
14089 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14090 type(104) and switching encryption type to 40*/
14091 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14092 eCSR_ENCRYPT_TYPE_WEP40;
14093 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14094 eCSR_ENCRYPT_TYPE_WEP40;
14095 }
14096
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014097 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014098 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014099
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014101 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014103
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 if ( 0 != status )
14105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014106 hddLog(VOS_TRACE_LEVEL_ERROR,
14107 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 status);
14109 return -EINVAL;
14110 }
14111 }
14112 }
14113
14114 /* In SoftAp mode setting key direction for default mode */
14115 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14116 {
14117 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14118 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14119 (eCSR_ENCRYPT_TYPE_AES !=
14120 pWextState->roamProfile.EncryptionType.encryptionType[0])
14121 )
14122 {
14123 /* Saving key direction for default key index to TX default */
14124 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14125 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14126 }
14127 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014128 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014129 return status;
14130}
14131
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14133static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14134 struct net_device *ndev,
14135 u8 key_index,
14136 bool unicast, bool multicast)
14137#else
14138static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14139 struct net_device *ndev,
14140 u8 key_index)
14141#endif
14142{
14143 int ret;
14144 vos_ssr_protect(__func__);
14145#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14146 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14147 multicast);
14148#else
14149 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14150#endif
14151 vos_ssr_unprotect(__func__);
14152
14153 return ret;
14154}
14155
Jeff Johnson295189b2012-06-20 16:38:30 -070014156/*
14157 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14158 * This function is used to inform the BSS details to nl80211 interface.
14159 */
14160static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14161 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14162{
14163 struct net_device *dev = pAdapter->dev;
14164 struct wireless_dev *wdev = dev->ieee80211_ptr;
14165 struct wiphy *wiphy = wdev->wiphy;
14166 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14167 int chan_no;
14168 int ie_length;
14169 const char *ie;
14170 unsigned int freq;
14171 struct ieee80211_channel *chan;
14172 int rssi = 0;
14173 struct cfg80211_bss *bss = NULL;
14174
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 if( NULL == pBssDesc )
14176 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014178 return bss;
14179 }
14180
14181 chan_no = pBssDesc->channelId;
14182 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14183 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14184
14185 if( NULL == ie )
14186 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014187 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014188 return bss;
14189 }
14190
14191#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14192 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14193 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014194 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 }
14196 else
14197 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014198 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014199 }
14200#else
14201 freq = ieee80211_channel_to_frequency(chan_no);
14202#endif
14203
14204 chan = __ieee80211_get_channel(wiphy, freq);
14205
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014206 if (!chan) {
14207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14208 return NULL;
14209 }
14210
Abhishek Singhaee43942014-06-16 18:55:47 +053014211 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014212
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014213 return cfg80211_inform_bss(wiphy, chan,
14214#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14215 CFG80211_BSS_FTYPE_UNKNOWN,
14216#endif
14217 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014218 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014219 pBssDesc->capabilityInfo,
14220 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014221 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014222}
14223
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014224/*
14225 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14226 * interface that BSS might have been lost.
14227 * @pAdapter: adaptor
14228 * @bssid: bssid which might have been lost
14229 *
14230 * Return: bss which is unlinked from kernel cache
14231 */
14232struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14233 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14234{
14235 struct net_device *dev = pAdapter->dev;
14236 struct wireless_dev *wdev = dev->ieee80211_ptr;
14237 struct wiphy *wiphy = wdev->wiphy;
14238 struct cfg80211_bss *bss = NULL;
14239
Abhishek Singh5a597e62016-12-05 15:16:30 +053014240 bss = hdd_get_bss_entry(wiphy,
14241 NULL, bssid,
14242 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014243 if (bss == NULL) {
14244 hddLog(LOGE, FL("BSS not present"));
14245 } else {
14246 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14247 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14248 cfg80211_unlink_bss(wiphy, bss);
14249 }
14250 return bss;
14251}
Jeff Johnson295189b2012-06-20 16:38:30 -070014252
14253
14254/*
14255 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14256 * This function is used to inform the BSS details to nl80211 interface.
14257 */
14258struct cfg80211_bss*
14259wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14260 tSirBssDescription *bss_desc
14261 )
14262{
14263 /*
14264 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14265 already exists in bss data base of cfg80211 for that particular BSS ID.
14266 Using cfg80211_inform_bss_frame to update the bss entry instead of
14267 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14268 now there is no possibility to get the mgmt(probe response) frame from PE,
14269 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14270 cfg80211_inform_bss_frame.
14271 */
14272 struct net_device *dev = pAdapter->dev;
14273 struct wireless_dev *wdev = dev->ieee80211_ptr;
14274 struct wiphy *wiphy = wdev->wiphy;
14275 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014276#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14277 qcom_ie_age *qie_age = NULL;
14278 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14279#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014281#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014282 const char *ie =
14283 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14284 unsigned int freq;
14285 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014286 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014288 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14289 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014290 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014291 hdd_context_t *pHddCtx;
14292 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014293#ifdef WLAN_OPEN_SOURCE
14294 struct timespec ts;
14295#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014297
Wilson Yangf80a0542013-10-07 13:02:37 -070014298 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14299 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014300 if (0 != status)
14301 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014302 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014303 }
14304
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014305 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014306 if (!mgmt)
14307 {
14308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14309 "%s: memory allocation failed ", __func__);
14310 return NULL;
14311 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014312
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014314
14315#ifdef WLAN_OPEN_SOURCE
14316 /* Android does not want the timestamp from the frame.
14317 Instead it wants a monotonic increasing value */
14318 get_monotonic_boottime(&ts);
14319 mgmt->u.probe_resp.timestamp =
14320 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14321#else
14322 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014323 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14324 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014325
14326#endif
14327
Jeff Johnson295189b2012-06-20 16:38:30 -070014328 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14329 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014330
14331#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14332 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14333 /* Assuming this is the last IE, copy at the end */
14334 ie_length -=sizeof(qcom_ie_age);
14335 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14336 qie_age->element_id = QCOM_VENDOR_IE_ID;
14337 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14338 qie_age->oui_1 = QCOM_OUI1;
14339 qie_age->oui_2 = QCOM_OUI2;
14340 qie_age->oui_3 = QCOM_OUI3;
14341 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014342 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14343 * bss related timestamp is in units of ms. Due to this when scan results
14344 * are sent to lowi the scan age is high.To address this, send age in units
14345 * of 1/10 ms.
14346 */
14347 qie_age->age = (vos_timer_get_system_time() -
14348 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014349#endif
14350
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014352 if (bss_desc->fProbeRsp)
14353 {
14354 mgmt->frame_control |=
14355 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14356 }
14357 else
14358 {
14359 mgmt->frame_control |=
14360 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14361 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014362
14363#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014364 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014365 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014366 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014367 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014368 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014369 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014370 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014371
14372 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014373 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 }
14375 else
14376 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14378 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 kfree(mgmt);
14380 return NULL;
14381 }
14382#else
14383 freq = ieee80211_channel_to_frequency(chan_no);
14384#endif
14385 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014386 /*when the band is changed on the fly using the GUI, three things are done
14387 * 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)
14388 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14389 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14390 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14391 * and discards the channels correponding to previous band and calls back with zero bss results.
14392 * 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
14393 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14394 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14395 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14396 * So drop the bss and continue to next bss.
14397 */
14398 if(chan == NULL)
14399 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014400 hddLog(VOS_TRACE_LEVEL_ERROR,
14401 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14402 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014403 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014404 return NULL;
14405 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014406 /*To keep the rssi icon of the connected AP in the scan window
14407 *and the rssi icon of the wireless networks in sync
14408 * */
14409 if (( eConnectionState_Associated ==
14410 pAdapter->sessionCtx.station.conn_info.connState ) &&
14411 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14412 pAdapter->sessionCtx.station.conn_info.bssId,
14413 WNI_CFG_BSSID_LEN)) &&
14414 (pHddCtx->hdd_wlan_suspended == FALSE))
14415 {
14416 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14417 rssi = (pAdapter->rssi * 100);
14418 }
14419 else
14420 {
14421 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014423
Nirav Shah20ac06f2013-12-12 18:14:06 +053014424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014425 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14426 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014427
Jeff Johnson295189b2012-06-20 16:38:30 -070014428 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14429 frame_len, rssi, GFP_KERNEL);
14430 kfree(mgmt);
14431 return bss_status;
14432}
14433
14434/*
14435 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14436 * This function is used to update the BSS data base of CFG8011
14437 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014438struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014439 tCsrRoamInfo *pRoamInfo
14440 )
14441{
14442 tCsrRoamConnectedProfile roamProfile;
14443 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14444 struct cfg80211_bss *bss = NULL;
14445
14446 ENTER();
14447
14448 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14449 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14450
14451 if (NULL != roamProfile.pBssDesc)
14452 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014453 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14454 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014455
14456 if (NULL == bss)
14457 {
14458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14459 __func__);
14460 }
14461
14462 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14463 }
14464 else
14465 {
14466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14467 __func__);
14468 }
14469 return bss;
14470}
14471
14472/*
14473 * FUNCTION: wlan_hdd_cfg80211_update_bss
14474 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014475static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14476 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014477 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014478{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014479 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 tCsrScanResultInfo *pScanResult;
14481 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014482 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 tScanResultHandle pResult;
14484 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014485 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014486 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014487 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014488
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014489 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14490 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14491 NO_SESSION, pAdapter->sessionId));
14492
Wilson Yangf80a0542013-10-07 13:02:37 -070014493 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014494 ret = wlan_hdd_validate_context(pHddCtx);
14495 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014497 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014498 }
14499
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014500 if (pAdapter->request != NULL)
14501 {
14502 if ((pAdapter->request->n_ssids == 1)
14503 && (pAdapter->request->ssids != NULL)
14504 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14505 is_p2p_scan = true;
14506 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014507 /*
14508 * start getting scan results and populate cgf80211 BSS database
14509 */
14510 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14511
14512 /* no scan results */
14513 if (NULL == pResult)
14514 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14516 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014517 wlan_hdd_get_frame_logs(pAdapter,
14518 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 return status;
14520 }
14521
14522 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14523
14524 while (pScanResult)
14525 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526 /*
14527 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14528 * entry already exists in bss data base of cfg80211 for that
14529 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14530 * bss entry instead of cfg80211_inform_bss, But this call expects
14531 * mgmt packet as input. As of now there is no possibility to get
14532 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014533 * ieee80211_mgmt(probe response) and passing to c
14534 * fg80211_inform_bss_frame.
14535 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014536 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14537 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14538 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014539 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14540 continue; //Skip the non p2p bss entries
14541 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014542 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14543 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014544
Jeff Johnson295189b2012-06-20 16:38:30 -070014545
14546 if (NULL == bss_status)
14547 {
14548 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014549 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014550 }
14551 else
14552 {
Yue Maf49ba872013-08-19 12:04:25 -070014553 cfg80211_put_bss(
14554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14555 wiphy,
14556#endif
14557 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014558 }
14559
14560 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14561 }
14562
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014563 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014564 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014565 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014566}
14567
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014568void
14569hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14570{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014571 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014572 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014573} /****** end hddPrintMacAddr() ******/
14574
14575void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014576hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014577{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014578 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014579 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014580 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14581 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14582 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014583} /****** end hddPrintPmkId() ******/
14584
14585//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14586//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14587
14588//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14589//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14590
14591#define dump_bssid(bssid) \
14592 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014593 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14594 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014595 }
14596
14597#define dump_pmkid(pMac, pmkid) \
14598 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014599 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14600 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014601 }
14602
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014603#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014604/*
14605 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14606 * This function is used to notify the supplicant of a new PMKSA candidate.
14607 */
14608int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014609 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014610 int index, bool preauth )
14611{
Jeff Johnsone7245742012-09-05 17:12:55 -070014612#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014613 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014614 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014615
14616 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014617 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014618
14619 if( NULL == pRoamInfo )
14620 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014621 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014622 return -EINVAL;
14623 }
14624
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014625 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14626 {
14627 dump_bssid(pRoamInfo->bssid);
14628 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014629 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014630 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014631#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014632 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014633}
14634#endif //FEATURE_WLAN_LFR
14635
Yue Maef608272013-04-08 23:09:17 -070014636#ifdef FEATURE_WLAN_LFR_METRICS
14637/*
14638 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14639 * 802.11r/LFR metrics reporting function to report preauth initiation
14640 *
14641 */
14642#define MAX_LFR_METRICS_EVENT_LENGTH 100
14643VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14644 tCsrRoamInfo *pRoamInfo)
14645{
14646 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14647 union iwreq_data wrqu;
14648
14649 ENTER();
14650
14651 if (NULL == pAdapter)
14652 {
14653 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14654 return VOS_STATUS_E_FAILURE;
14655 }
14656
14657 /* create the event */
14658 memset(&wrqu, 0, sizeof(wrqu));
14659 memset(metrics_notification, 0, sizeof(metrics_notification));
14660
14661 wrqu.data.pointer = metrics_notification;
14662 wrqu.data.length = scnprintf(metrics_notification,
14663 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14664 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14665
14666 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14667
14668 EXIT();
14669
14670 return VOS_STATUS_SUCCESS;
14671}
14672
14673/*
14674 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14675 * 802.11r/LFR metrics reporting function to report preauth completion
14676 * or failure
14677 */
14678VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14679 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14680{
14681 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14682 union iwreq_data wrqu;
14683
14684 ENTER();
14685
14686 if (NULL == pAdapter)
14687 {
14688 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14689 return VOS_STATUS_E_FAILURE;
14690 }
14691
14692 /* create the event */
14693 memset(&wrqu, 0, sizeof(wrqu));
14694 memset(metrics_notification, 0, sizeof(metrics_notification));
14695
14696 scnprintf(metrics_notification, sizeof(metrics_notification),
14697 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14698 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14699
14700 if (1 == preauth_status)
14701 strncat(metrics_notification, " TRUE", 5);
14702 else
14703 strncat(metrics_notification, " FALSE", 6);
14704
14705 wrqu.data.pointer = metrics_notification;
14706 wrqu.data.length = strlen(metrics_notification);
14707
14708 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14709
14710 EXIT();
14711
14712 return VOS_STATUS_SUCCESS;
14713}
14714
14715/*
14716 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14717 * 802.11r/LFR metrics reporting function to report handover initiation
14718 *
14719 */
14720VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14721 tCsrRoamInfo *pRoamInfo)
14722{
14723 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14724 union iwreq_data wrqu;
14725
14726 ENTER();
14727
14728 if (NULL == pAdapter)
14729 {
14730 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14731 return VOS_STATUS_E_FAILURE;
14732 }
14733
14734 /* create the event */
14735 memset(&wrqu, 0, sizeof(wrqu));
14736 memset(metrics_notification, 0, sizeof(metrics_notification));
14737
14738 wrqu.data.pointer = metrics_notification;
14739 wrqu.data.length = scnprintf(metrics_notification,
14740 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14741 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14742
14743 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14744
14745 EXIT();
14746
14747 return VOS_STATUS_SUCCESS;
14748}
14749#endif
14750
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014751
14752/**
14753 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14754 * @scan_req: scan request to be checked
14755 *
14756 * Return: true or false
14757 */
14758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14759static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14760 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014761 *scan_req, hdd_context_t
14762 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014763{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014764 if (!scan_req || !scan_req->wiphy ||
14765 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014766 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14767 return false;
14768 }
14769 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14770 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14771 return false;
14772 }
14773 return true;
14774}
14775#else
14776static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14777 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014778 *scan_req, hdd_context_t
14779 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014780{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014781 if (!scan_req || !scan_req->wiphy ||
14782 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014783 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14784 return false;
14785 }
14786 return true;
14787}
14788#endif
14789
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14791/**
14792 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14793 * @adapter: Pointer to the adapter
14794 * @req : Scan request
14795 * @aborted : true scan aborted false scan success
14796 *
14797 * This function notifies scan done to cfg80211
14798 *
14799 * Return: none
14800 */
14801static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14802 struct cfg80211_scan_request *req,
14803 bool aborted)
14804{
14805 struct cfg80211_scan_info info = {
14806 .aborted = aborted
14807 };
14808
14809 if (adapter->dev->flags & IFF_UP)
14810 cfg80211_scan_done(req, &info);
14811 else
14812 hddLog(LOGW,
14813 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14814}
14815#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14816/**
14817 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14818 * @adapter: Pointer to the adapter
14819 * @req : Scan request
14820 * @aborted : true scan aborted false scan success
14821 *
14822 * This function notifies scan done to cfg80211
14823 *
14824 * Return: none
14825 */
14826static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14827 struct cfg80211_scan_request *req,
14828 bool aborted)
14829{
14830 if (adapter->dev->flags & IFF_UP)
14831 cfg80211_scan_done(req, aborted);
14832 else
14833 hddLog(LOGW,
14834 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14835}
14836#else
14837/**
14838 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14839 * @adapter: Pointer to the adapter
14840 * @req : Scan request
14841 * @aborted : true scan aborted false scan success
14842 *
14843 * This function notifies scan done to cfg80211
14844 *
14845 * Return: none
14846 */
14847static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14848 struct cfg80211_scan_request *req,
14849 bool aborted)
14850{
14851 cfg80211_scan_done(req, aborted);
14852}
14853#endif
14854
Mukul Sharmab392b642017-08-17 17:45:29 +053014855#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014856/*
14857 * FUNCTION: hdd_cfg80211_scan_done_callback
14858 * scanning callback function, called after finishing scan
14859 *
14860 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014861static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014862 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14863{
14864 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014865 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014867 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014868 struct cfg80211_scan_request *req = NULL;
14869 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014870 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014871 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014872 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014873
14874 ENTER();
14875
c_manjee1b4ab9a2016-10-26 11:36:55 +053014876 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14877 !pAdapter->dev) {
14878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14879 return 0;
14880 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014881 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014882 if (NULL == pHddCtx) {
14883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014884 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014885 }
14886
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014888 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014889 {
14890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014891 }
14892#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014893 pScanInfo = &pHddCtx->scan_info;
14894
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014896 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014897 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014898 __func__, halHandle, pContext, (int) scanId, (int) status);
14899
Kiet Lamac06e2c2013-10-23 16:25:07 +053014900 pScanInfo->mScanPendingCounter = 0;
14901
Jeff Johnson295189b2012-06-20 16:38:30 -070014902 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014903 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 &pScanInfo->scan_req_completion_event,
14905 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014906 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014907 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014908 hddLog(VOS_TRACE_LEVEL_ERROR,
14909 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014910 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014911 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 }
14913
Yue Maef608272013-04-08 23:09:17 -070014914 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 {
14916 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014917 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014918 }
14919
14920 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014921 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 {
14923 hddLog(VOS_TRACE_LEVEL_INFO,
14924 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014925 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014926 (int) scanId);
14927 }
14928
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014929#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014930 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014931#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014932 {
14933 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14934 pAdapter);
14935 if (0 > ret)
14936 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014937 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014938
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 /* If any client wait scan result through WEXT
14940 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014941 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 {
14943 /* The other scan request waiting for current scan finish
14944 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014945 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014947 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 }
14949 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014950 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 {
14952 struct net_device *dev = pAdapter->dev;
14953 union iwreq_data wrqu;
14954 int we_event;
14955 char *msg;
14956
14957 memset(&wrqu, '\0', sizeof(wrqu));
14958 we_event = SIOCGIWSCAN;
14959 msg = NULL;
14960 wireless_send_event(dev, we_event, &wrqu, msg);
14961 }
14962 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014963 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014964
14965 /* Get the Scan Req */
14966 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014967 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014968
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014969 /* Scan is no longer pending */
14970 pScanInfo->mScanPending = VOS_FALSE;
14971
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014972 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014974#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014976 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014977#endif
14978
14979 if (pAdapter->dev) {
14980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14981 pAdapter->dev->name);
14982 }
mukul sharmae7041822015-12-03 15:09:21 +053014983 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014984 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 }
14986
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014987 /* last_scan_timestamp is used to decide if new scan
14988 * is needed or not on station interface. If last station
14989 * scan time and new station scan time is less then
14990 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014991 * Also only last_scan_timestamp is updated here last_scan_channellist
14992 * is updated on receiving scan request itself to make sure kernel
14993 * allocated scan request(scan_req) object is not dereferenced here,
14994 * because interface down, where kernel frees scan_req, may happen any
14995 * time while driver is processing scan_done_callback. So it's better
14996 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014997 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014998 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14999 if (status == eCSR_SCAN_SUCCESS)
15000 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15001 else {
15002 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15003 sizeof(pHddCtx->scan_info.last_scan_channelList));
15004 pHddCtx->scan_info.last_scan_numChannels = 0;
15005 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015006 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015007 }
15008
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015009 /*
15010 * cfg80211_scan_done informing NL80211 about completion
15011 * of scanning
15012 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015013 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15014 {
15015 aborted = true;
15016 }
mukul sharmae7041822015-12-03 15:09:21 +053015017
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015019 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15020 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015021#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015022 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015023
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015024 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015025
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015026allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015027 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15028 ) && (pHddCtx->spoofMacAddr.isEnabled
15029 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015030 /* Generate new random mac addr for next scan */
15031 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015032
15033 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15034 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015035 }
15036
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015037 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015038 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015039
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015040 /* Acquire wakelock to handle the case where APP's tries to suspend
15041 * immediatly after the driver gets connect request(i.e after scan)
15042 * from supplicant, this result in app's is suspending and not able
15043 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015044 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015045
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015047 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015048#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015049#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015050 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015051#endif
15052
Jeff Johnson295189b2012-06-20 16:38:30 -070015053 EXIT();
15054 return 0;
15055}
15056
15057/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015058 * FUNCTION: hdd_isConnectionInProgress
15059 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015060 *
15061 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015062v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15063 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015064{
15065 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15066 hdd_station_ctx_t *pHddStaCtx = NULL;
15067 hdd_adapter_t *pAdapter = NULL;
15068 VOS_STATUS status = 0;
15069 v_U8_t staId = 0;
15070 v_U8_t *staMac = NULL;
15071
15072 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15073
15074 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15075 {
15076 pAdapter = pAdapterNode->pAdapter;
15077
15078 if( pAdapter )
15079 {
15080 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015081 "%s: Adapter with device mode %s (%d) exists",
15082 __func__, hdd_device_modetoString(pAdapter->device_mode),
15083 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015084 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015085 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15086 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15087 (eConnectionState_Connecting ==
15088 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15089 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015090 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015091 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015092 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015093 if (session_id && reason)
15094 {
15095 *session_id = pAdapter->sessionId;
15096 *reason = eHDD_CONNECTION_IN_PROGRESS;
15097 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015098 return VOS_TRUE;
15099 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015100 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015101 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015102 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015103 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015104 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015105 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015106 if (session_id && reason)
15107 {
15108 *session_id = pAdapter->sessionId;
15109 *reason = eHDD_REASSOC_IN_PROGRESS;
15110 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015111 return VOS_TRUE;
15112 }
15113 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015114 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15115 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015116 {
15117 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15118 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015119 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15120 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015121 {
15122 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015123 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015124 "%s: client " MAC_ADDRESS_STR
15125 " is in the middle of WPS/EAPOL exchange.", __func__,
15126 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015127 if (session_id && reason)
15128 {
15129 *session_id = pAdapter->sessionId;
15130 *reason = eHDD_EAPOL_IN_PROGRESS;
15131 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015132 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015133 }
15134 }
15135 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15136 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15137 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015138 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15139 ptSapContext pSapCtx = NULL;
15140 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15141 if(pSapCtx == NULL){
15142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15143 FL("psapCtx is NULL"));
15144 return VOS_FALSE;
15145 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015146 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15147 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015148 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15149 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015150 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015151 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015152
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015153 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015154 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15155 "middle of WPS/EAPOL exchange.", __func__,
15156 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015157 if (session_id && reason)
15158 {
15159 *session_id = pAdapter->sessionId;
15160 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15161 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015162 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015163 }
15164 }
15165 }
15166 }
15167 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15168 pAdapterNode = pNext;
15169 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015170 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015171}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015172
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015173/**
15174 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15175 * to the Scan request
15176 * @scanRequest: Pointer to the csr scan request
15177 * @request: Pointer to the scan request from supplicant
15178 *
15179 * Return: None
15180 */
15181#ifdef CFG80211_SCAN_BSSID
15182static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15183 struct cfg80211_scan_request *request)
15184{
15185 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15186}
15187#else
15188static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15189 struct cfg80211_scan_request *request)
15190{
15191}
15192#endif
15193
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015194/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015195 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015196 * this scan respond to scan trigger and update cfg80211 scan database
15197 * later, scan dump command can be used to recieve scan results
15198 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015199int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015200#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15201 struct net_device *dev,
15202#endif
15203 struct cfg80211_scan_request *request)
15204{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015205 hdd_adapter_t *pAdapter = NULL;
15206 hdd_context_t *pHddCtx = NULL;
15207 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015208 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015209 tCsrScanRequest scanRequest;
15210 tANI_U8 *channelList = NULL, i;
15211 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015212 int status;
15213 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015214 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015215 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015216 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015217 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015218 v_U8_t curr_session_id;
15219 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015220
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15222 struct net_device *dev = NULL;
15223 if (NULL == request)
15224 {
15225 hddLog(VOS_TRACE_LEVEL_ERROR,
15226 "%s: scan req param null", __func__);
15227 return -EINVAL;
15228 }
15229 dev = request->wdev->netdev;
15230#endif
15231
15232 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15233 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15234 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15235
Jeff Johnson295189b2012-06-20 16:38:30 -070015236 ENTER();
15237
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15239 __func__, hdd_device_modetoString(pAdapter->device_mode),
15240 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015241
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015242 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015243 if (0 != status)
15244 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015245 return status;
15246 }
15247
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015248 if (NULL == pwextBuf)
15249 {
15250 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15251 __func__);
15252 return -EIO;
15253 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015254 cfg_param = pHddCtx->cfg_ini;
15255 pScanInfo = &pHddCtx->scan_info;
15256
Jeff Johnson295189b2012-06-20 16:38:30 -070015257#ifdef WLAN_BTAMP_FEATURE
15258 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015259 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015261 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 "%s: No scanning when AMP is on", __func__);
15263 return -EOPNOTSUPP;
15264 }
15265#endif
15266 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015267 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015269 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015270 "%s: Not scanning on device_mode = %s (%d)",
15271 __func__, hdd_device_modetoString(pAdapter->device_mode),
15272 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 return -EOPNOTSUPP;
15274 }
15275
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015276 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15277 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15278 return -EOPNOTSUPP;
15279 }
15280
Jeff Johnson295189b2012-06-20 16:38:30 -070015281 if (TRUE == pScanInfo->mScanPending)
15282 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015283 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15284 {
15285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15286 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015287 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 }
15289
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015290 // Don't allow scan if PNO scan is going on.
15291 if (pHddCtx->isPnoEnable)
15292 {
15293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15294 FL("pno scan in progress"));
15295 return -EBUSY;
15296 }
15297
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015298 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015299 //Channel and action frame is pending
15300 //Otherwise Cancel Remain On Channel and allow Scan
15301 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015302 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015303 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015305 return -EBUSY;
15306 }
15307
Jeff Johnson295189b2012-06-20 16:38:30 -070015308 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15309 {
15310 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015311 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015312 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015313 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015314 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15315 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015316 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 "%s: MAX TM Level Scan not allowed", __func__);
15318 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015319 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015320 }
15321 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15322
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015323 /* Check if scan is allowed at this point of time.
15324 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015325 if (TRUE == pHddCtx->btCoexModeSet)
15326 {
15327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15328 FL("BTCoex Mode operation in progress"));
15329 return -EBUSY;
15330 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015331 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015332 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015333
15334 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15335 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15336 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015337 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15338 pHddCtx->last_scan_reject_reason != curr_reason ||
15339 !pHddCtx->last_scan_reject_timestamp)
15340 {
15341 pHddCtx->last_scan_reject_session_id = curr_session_id;
15342 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015343 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015344 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015345 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015346 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015347 else
15348 {
15349 pHddCtx->scan_reject_cnt++;
15350
Abhishek Singhe4b12562017-06-20 16:53:39 +053015351 if ((pHddCtx->scan_reject_cnt >=
15352 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015353 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015354 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015355 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015356 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015357 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015358 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015359 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015360 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015361 if (pHddCtx->cfg_ini->enableFatalEvent)
15362 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15363 WLAN_LOG_INDICATOR_HOST_DRIVER,
15364 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15365 FALSE, FALSE);
15366 else
15367 {
15368 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015369 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015370 }
15371 }
15372 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015373 return -EBUSY;
15374 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015375 pHddCtx->last_scan_reject_timestamp = 0;
15376 pHddCtx->last_scan_reject_session_id = 0xFF;
15377 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015378 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015379
Jeff Johnson295189b2012-06-20 16:38:30 -070015380 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15381
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015382 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15383 * Becasue of this, driver is assuming that this is not wildcard scan and so
15384 * is not aging out the scan results.
15385 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015386 if ((request->ssids) && (request->n_ssids == 1) &&
15387 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015388 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015389 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015390
15391 if ((request->ssids) && (0 < request->n_ssids))
15392 {
15393 tCsrSSIDInfo *SsidInfo;
15394 int j;
15395 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15396 /* Allocate num_ssid tCsrSSIDInfo structure */
15397 SsidInfo = scanRequest.SSIDs.SSIDList =
15398 ( tCsrSSIDInfo *)vos_mem_malloc(
15399 request->n_ssids*sizeof(tCsrSSIDInfo));
15400
15401 if(NULL == scanRequest.SSIDs.SSIDList)
15402 {
15403 hddLog(VOS_TRACE_LEVEL_ERROR,
15404 "%s: memory alloc failed SSIDInfo buffer", __func__);
15405 return -ENOMEM;
15406 }
15407
15408 /* copy all the ssid's and their length */
15409 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15410 {
15411 /* get the ssid length */
15412 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15413 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15414 SsidInfo->SSID.length);
15415 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15416 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15417 j, SsidInfo->SSID.ssId);
15418 }
15419 /* set the scan type to active */
15420 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15421 }
15422 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015424 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15425 TRACE_CODE_HDD_CFG80211_SCAN,
15426 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015427 /* set the scan type to active */
15428 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015430 else
15431 {
15432 /*Set the scan type to default type, in this case it is ACTIVE*/
15433 scanRequest.scanType = pScanInfo->scan_mode;
15434 }
15435 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15436 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015437
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015438 csr_scan_request_assign_bssid(&scanRequest, request);
15439
Jeff Johnson295189b2012-06-20 16:38:30 -070015440 /* set BSSType to default type */
15441 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15442
15443 /*TODO: scan the requested channels only*/
15444
15445 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015446 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015447 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015448 hddLog(VOS_TRACE_LEVEL_WARN,
15449 "No of Scan Channels exceeded limit: %d", request->n_channels);
15450 request->n_channels = MAX_CHANNEL;
15451 }
15452
15453 hddLog(VOS_TRACE_LEVEL_INFO,
15454 "No of Scan Channels: %d", request->n_channels);
15455
15456
15457 if( request->n_channels )
15458 {
15459 char chList [(request->n_channels*5)+1];
15460 int len;
15461 channelList = vos_mem_malloc( request->n_channels );
15462 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015463 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015464 hddLog(VOS_TRACE_LEVEL_ERROR,
15465 "%s: memory alloc failed channelList", __func__);
15466 status = -ENOMEM;
15467 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015468 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015469
15470 for( i = 0, len = 0; i < request->n_channels ; i++ )
15471 {
15472 channelList[i] = request->channels[i]->hw_value;
15473 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15474 }
15475
Nirav Shah20ac06f2013-12-12 18:14:06 +053015476 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015477 "Channel-List: %s ", chList);
15478 }
c_hpothu53512302014-04-15 18:49:53 +053015479
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015480 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15481 scanRequest.ChannelInfo.ChannelList = channelList;
15482
15483 /* set requestType to full scan */
15484 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15485
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015486 /* if there is back to back scan happening in driver with in
15487 * nDeferScanTimeInterval interval driver should defer new scan request
15488 * and should provide last cached scan results instead of new channel list.
15489 * This rule is not applicable if scan is p2p scan.
15490 * This condition will work only in case when last request no of channels
15491 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015492 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015493 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015494 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015495
Sushant Kaushik86592172015-04-27 16:35:03 +053015496 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15497 /* if wps ie is NULL , then only defer scan */
15498 if ( pWpsIe == NULL &&
15499 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015500 {
15501 if ( pScanInfo->last_scan_timestamp !=0 &&
15502 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15503 {
15504 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15505 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15506 vos_mem_compare(pScanInfo->last_scan_channelList,
15507 channelList, pScanInfo->last_scan_numChannels))
15508 {
15509 hddLog(VOS_TRACE_LEVEL_WARN,
15510 " New and old station scan time differ is less then %u",
15511 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15512
15513 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015514 pAdapter);
15515
Agarwal Ashish57e84372014-12-05 18:26:53 +053015516 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015517 "Return old cached scan as all channels and no of channels are same");
15518
Agarwal Ashish57e84372014-12-05 18:26:53 +053015519 if (0 > ret)
15520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015521
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015522 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015523
15524 status = eHAL_STATUS_SUCCESS;
15525 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015526 }
15527 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015528 }
15529
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015530 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15531 * search (Flush on both full scan and social scan but not on single
15532 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15533 */
15534
15535 /* Supplicant does single channel scan after 8-way handshake
15536 * and in that case driver shoudnt flush scan results. If
15537 * driver flushes the scan results here and unfortunately if
15538 * the AP doesnt respond to our probe req then association
15539 * fails which is not desired
15540 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015541 if ((request->n_ssids == 1)
15542 && (request->ssids != NULL)
15543 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15544 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015545
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015546 if( is_p2p_scan ||
15547 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015548 {
15549 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15550 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15551 pAdapter->sessionId );
15552 }
15553
15554 if( request->ie_len )
15555 {
15556 /* save this for future association (join requires this) */
15557 /*TODO: Array needs to be converted to dynamic allocation,
15558 * as multiple ie.s can be sent in cfg80211_scan_request structure
15559 * CR 597966
15560 */
15561 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15562 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15563 pScanInfo->scanAddIE.length = request->ie_len;
15564
15565 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15566 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15567 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015568 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015569 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015571 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15572 memcpy( pwextBuf->roamProfile.addIEScan,
15573 request->ie, request->ie_len);
15574 }
15575 else
15576 {
15577 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15578 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015579 }
15580
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015581 }
15582 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15583 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15584
15585 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15586 request->ie_len);
15587 if (pP2pIe != NULL)
15588 {
15589#ifdef WLAN_FEATURE_P2P_DEBUG
15590 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15591 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15592 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015593 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015594 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15595 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15596 "Go nego completed to Connection is started");
15597 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15598 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015599 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015600 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15601 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015602 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015603 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15604 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15605 "Disconnected state to Connection is started");
15606 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15607 "for 4way Handshake");
15608 }
15609#endif
15610
15611 /* no_cck will be set during p2p find to disable 11b rates */
15612 if(TRUE == request->no_cck)
15613 {
15614 hddLog(VOS_TRACE_LEVEL_INFO,
15615 "%s: This is a P2P Search", __func__);
15616 scanRequest.p2pSearch = 1;
15617
15618 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015619 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015620 /* set requestType to P2P Discovery */
15621 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15622 }
15623
15624 /*
15625 Skip Dfs Channel in case of P2P Search
15626 if it is set in ini file
15627 */
15628 if(cfg_param->skipDfsChnlInP2pSearch)
15629 {
15630 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015631 }
15632 else
15633 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015634 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015635 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015636
Agarwal Ashish4f616132013-12-30 23:32:50 +053015637 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015638 }
15639 }
15640
15641 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15642
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015643#ifdef FEATURE_WLAN_TDLS
15644 /* if tdls disagree scan right now, return immediately.
15645 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15646 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15647 */
15648 status = wlan_hdd_tdls_scan_callback (pAdapter,
15649 wiphy,
15650#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15651 dev,
15652#endif
15653 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015654 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015655 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015656 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15658 "scan rejected %d", __func__, status);
15659 else
15660 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15661 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015662 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015663 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015664 }
15665#endif
15666
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015667 /* acquire the wakelock to avoid the apps suspend during the scan. To
15668 * address the following issues.
15669 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15670 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15671 * for long time, this result in apps running at full power for long time.
15672 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15673 * be stuck in full power because of resume BMPS
15674 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015675 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015676
Nirav Shah20ac06f2013-12-12 18:14:06 +053015677 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15678 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015679 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15680 scanRequest.requestType, scanRequest.scanType,
15681 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015682 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15683
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015684 if (pHddCtx->spoofMacAddr.isEnabled &&
15685 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015686 {
15687 hddLog(VOS_TRACE_LEVEL_INFO,
15688 "%s: MAC Spoofing enabled for current scan", __func__);
15689 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15690 * to fill TxBds for probe request during current scan
15691 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015692 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015693 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015694
15695 if(status != VOS_STATUS_SUCCESS)
15696 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015697 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015698 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015699#ifdef FEATURE_WLAN_TDLS
15700 wlan_hdd_tdls_scan_done_callback(pAdapter);
15701#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015702 goto free_mem;
15703 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015704 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015705 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015706 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015707 pAdapter->sessionId, &scanRequest, &scanId,
15708 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015709
Jeff Johnson295189b2012-06-20 16:38:30 -070015710 if (eHAL_STATUS_SUCCESS != status)
15711 {
15712 hddLog(VOS_TRACE_LEVEL_ERROR,
15713 "%s: sme_ScanRequest returned error %d", __func__, status);
15714 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015715 if(eHAL_STATUS_RESOURCES == status)
15716 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15718 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015719 status = -EBUSY;
15720 } else {
15721 status = -EIO;
15722 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015723 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015724
15725#ifdef FEATURE_WLAN_TDLS
15726 wlan_hdd_tdls_scan_done_callback(pAdapter);
15727#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015728 goto free_mem;
15729 }
15730
15731 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015732 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015733 pAdapter->request = request;
15734 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015735 pScanInfo->no_cck = request->no_cck;
15736 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15737 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15738 pHddCtx->scan_info.last_scan_channelList[i] =
15739 request->channels[i]->hw_value;
15740 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015741
15742 complete(&pScanInfo->scan_req_completion_event);
15743
15744free_mem:
15745 if( scanRequest.SSIDs.SSIDList )
15746 {
15747 vos_mem_free(scanRequest.SSIDs.SSIDList);
15748 }
15749
15750 if( channelList )
15751 vos_mem_free( channelList );
15752
15753 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015754 return status;
15755}
15756
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015757int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15758#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15759 struct net_device *dev,
15760#endif
15761 struct cfg80211_scan_request *request)
15762{
15763 int ret;
15764
15765 vos_ssr_protect(__func__);
15766 ret = __wlan_hdd_cfg80211_scan(wiphy,
15767#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15768 dev,
15769#endif
15770 request);
15771 vos_ssr_unprotect(__func__);
15772
15773 return ret;
15774}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015775
15776void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15777{
15778 v_U8_t iniDot11Mode =
15779 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15780 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15781
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015782 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15783 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015784 switch ( iniDot11Mode )
15785 {
15786 case eHDD_DOT11_MODE_AUTO:
15787 case eHDD_DOT11_MODE_11ac:
15788 case eHDD_DOT11_MODE_11ac_ONLY:
15789#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015790 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15791 sme_IsFeatureSupportedByFW(DOT11AC) )
15792 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15793 else
15794 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015795#else
15796 hddDot11Mode = eHDD_DOT11_MODE_11n;
15797#endif
15798 break;
15799 case eHDD_DOT11_MODE_11n:
15800 case eHDD_DOT11_MODE_11n_ONLY:
15801 hddDot11Mode = eHDD_DOT11_MODE_11n;
15802 break;
15803 default:
15804 hddDot11Mode = iniDot11Mode;
15805 break;
15806 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015807#ifdef WLAN_FEATURE_AP_HT40_24G
15808 if (operationChannel > SIR_11B_CHANNEL_END)
15809#endif
15810 {
15811 /* This call decides required channel bonding mode */
15812 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015813 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015814 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015815 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015816}
15817
Jeff Johnson295189b2012-06-20 16:38:30 -070015818/*
15819 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015820 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015821 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015822int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015823 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15824 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015825{
15826 int status = 0;
15827 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015828 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015829 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015830 v_U32_t roamId;
15831 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015832 eCsrAuthType RSNAuthType;
15833
15834 ENTER();
15835
15836 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015837 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015838 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015839
15840 status = wlan_hdd_validate_context(pHddCtx);
15841 if (status)
15842 {
Yue Mae36e3552014-03-05 17:06:20 -080015843 return status;
15844 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015845
Jeff Johnson295189b2012-06-20 16:38:30 -070015846 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15847 {
15848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15849 return -EINVAL;
15850 }
15851
Nitesh Shah9b066282017-06-06 18:05:52 +053015852
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 pRoamProfile = &pWextState->roamProfile;
15854
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015855 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015856 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015857 hdd_station_ctx_t *pHddStaCtx;
15858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015859 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015860
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015861 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15862
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015863 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015864 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15865 {
15866 /*QoS not enabled in cfg file*/
15867 pRoamProfile->uapsd_mask = 0;
15868 }
15869 else
15870 {
15871 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015872 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015873 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15874 }
15875
15876 pRoamProfile->SSIDs.numOfSSIDs = 1;
15877 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15878 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15881 ssid, ssid_len);
15882
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015883 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15884 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15885
Jeff Johnson295189b2012-06-20 16:38:30 -070015886 if (bssid)
15887 {
15888 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015889 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015890 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 /* Save BSSID in seperate variable as well, as RoamProfile
15892 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 case of join failure we should send valid BSSID to supplicant
15894 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015895 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015896 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015897
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015899 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015900 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015901 /* Store bssid_hint to use in the scan filter. */
15902 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15903 WNI_CFG_BSSID_LEN);
15904 /*
15905 * Save BSSID in seperate variable as well, as RoamProfile
15906 * BSSID is getting zeroed out in the association process. And in
15907 * case of join failure we should send valid BSSID to supplicant
15908 */
15909 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15910 WNI_CFG_BSSID_LEN);
15911 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15912 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015913 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015914
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015915
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015916 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15917 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015918 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15919 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015920 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015921 /*set gen ie*/
15922 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15923 /*set auth*/
15924 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15925 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015926#ifdef FEATURE_WLAN_WAPI
15927 if (pAdapter->wapi_info.nWapiMode)
15928 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015929 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015930 switch (pAdapter->wapi_info.wapiAuthMode)
15931 {
15932 case WAPI_AUTH_MODE_PSK:
15933 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015934 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015935 pAdapter->wapi_info.wapiAuthMode);
15936 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15937 break;
15938 }
15939 case WAPI_AUTH_MODE_CERT:
15940 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015941 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 pAdapter->wapi_info.wapiAuthMode);
15943 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15944 break;
15945 }
15946 } // End of switch
15947 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15948 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15949 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015950 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015951 pRoamProfile->AuthType.numEntries = 1;
15952 pRoamProfile->EncryptionType.numEntries = 1;
15953 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15954 pRoamProfile->mcEncryptionType.numEntries = 1;
15955 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15956 }
15957 }
15958#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015959#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015960 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015961 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15962 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15963 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015964 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15965 sizeof (tSirGtkOffloadParams));
15966 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015967 }
15968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015969 pRoamProfile->csrPersona = pAdapter->device_mode;
15970
Jeff Johnson32d95a32012-09-10 13:15:23 -070015971 if( operatingChannel )
15972 {
15973 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15974 pRoamProfile->ChannelInfo.numOfChannels = 1;
15975 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015976 else
15977 {
15978 pRoamProfile->ChannelInfo.ChannelList = NULL;
15979 pRoamProfile->ChannelInfo.numOfChannels = 0;
15980 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015981 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15982 {
15983 hdd_select_cbmode(pAdapter,operatingChannel);
15984 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015985
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015986 /*
15987 * Change conn_state to connecting before sme_RoamConnect(),
15988 * because sme_RoamConnect() has a direct path to call
15989 * hdd_smeRoamCallback(), which will change the conn_state
15990 * If direct path, conn_state will be accordingly changed
15991 * to NotConnected or Associated by either
15992 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15993 * in sme_RoamCallback()
15994 * if sme_RomConnect is to be queued,
15995 * Connecting state will remain until it is completed.
15996 * If connection state is not changed,
15997 * connection state will remain in eConnectionState_NotConnected state.
15998 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15999 * if conn state is eConnectionState_NotConnected.
16000 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16001 * informed of connect result indication which is an issue.
16002 */
16003
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016004 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16005 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016006 {
16007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016008 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016009 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16010 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016011 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16012 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016013 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016014
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016015 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016016 pAdapter->sessionId, pRoamProfile, &roamId);
16017
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016018 if ((eHAL_STATUS_SUCCESS != status) &&
16019 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16020 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016021
16022 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016023 hddLog(VOS_TRACE_LEVEL_ERROR,
16024 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16025 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016026 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016027 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016028 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016029 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016030
16031 pRoamProfile->ChannelInfo.ChannelList = NULL;
16032 pRoamProfile->ChannelInfo.numOfChannels = 0;
16033
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 }
16035 else
16036 {
16037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16038 return -EINVAL;
16039 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016040 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016041 return status;
16042}
16043
16044/*
16045 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16046 * This function is used to set the authentication type (OPEN/SHARED).
16047 *
16048 */
16049static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16050 enum nl80211_auth_type auth_type)
16051{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016052 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016053 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16054
16055 ENTER();
16056
16057 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016058 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016059 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016061 hddLog(VOS_TRACE_LEVEL_INFO,
16062 "%s: set authentication type to AUTOSWITCH", __func__);
16063 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16064 break;
16065
16066 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016067#ifdef WLAN_FEATURE_VOWIFI_11R
16068 case NL80211_AUTHTYPE_FT:
16069#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016070 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016071 "%s: set authentication type to OPEN", __func__);
16072 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16073 break;
16074
16075 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016076 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016077 "%s: set authentication type to SHARED", __func__);
16078 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16079 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016080#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016081 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016082 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016083 "%s: set authentication type to CCKM WPA", __func__);
16084 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16085 break;
16086#endif
16087
16088
16089 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016090 hddLog(VOS_TRACE_LEVEL_ERROR,
16091 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016092 auth_type);
16093 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16094 return -EINVAL;
16095 }
16096
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016097 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016098 pHddStaCtx->conn_info.authType;
16099 return 0;
16100}
16101
16102/*
16103 * FUNCTION: wlan_hdd_set_akm_suite
16104 * This function is used to set the key mgmt type(PSK/8021x).
16105 *
16106 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016107static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016108 u32 key_mgmt
16109 )
16110{
16111 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16112 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016113 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016114#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016115#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016116#endif
16117#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016118#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016120 /*set key mgmt type*/
16121 switch(key_mgmt)
16122 {
16123 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016124 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016125#ifdef WLAN_FEATURE_VOWIFI_11R
16126 case WLAN_AKM_SUITE_FT_PSK:
16127#endif
16128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016129 __func__);
16130 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16131 break;
16132
16133 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016134 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016135#ifdef WLAN_FEATURE_VOWIFI_11R
16136 case WLAN_AKM_SUITE_FT_8021X:
16137#endif
16138 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016139 __func__);
16140 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16141 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016142#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016143#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16144#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16145 case WLAN_AKM_SUITE_CCKM:
16146 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16147 __func__);
16148 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16149 break;
16150#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016151#ifndef WLAN_AKM_SUITE_OSEN
16152#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16153 case WLAN_AKM_SUITE_OSEN:
16154 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16155 __func__);
16156 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16157 break;
16158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016159
16160 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016162 __func__, key_mgmt);
16163 return -EINVAL;
16164
16165 }
16166 return 0;
16167}
16168
16169/*
16170 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016171 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 * (NONE/WEP40/WEP104/TKIP/CCMP).
16173 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016174static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16175 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 bool ucast
16177 )
16178{
16179 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016180 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016181 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16182
16183 ENTER();
16184
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016185 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016186 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016188 __func__, cipher);
16189 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16190 }
16191 else
16192 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016193
Jeff Johnson295189b2012-06-20 16:38:30 -070016194 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016195 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016196 {
16197 case IW_AUTH_CIPHER_NONE:
16198 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16199 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016200
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016202 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016204
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016206 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016207 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016208
Jeff Johnson295189b2012-06-20 16:38:30 -070016209 case WLAN_CIPHER_SUITE_TKIP:
16210 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16211 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016212
Jeff Johnson295189b2012-06-20 16:38:30 -070016213 case WLAN_CIPHER_SUITE_CCMP:
16214 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16215 break;
16216#ifdef FEATURE_WLAN_WAPI
16217 case WLAN_CIPHER_SUITE_SMS4:
16218 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16219 break;
16220#endif
16221
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016222#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016223 case WLAN_CIPHER_SUITE_KRK:
16224 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16225 break;
16226#endif
16227 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016229 __func__, cipher);
16230 return -EOPNOTSUPP;
16231 }
16232 }
16233
16234 if (ucast)
16235 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016236 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016237 __func__, encryptionType);
16238 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16239 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016240 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016241 encryptionType;
16242 }
16243 else
16244 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016245 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016246 __func__, encryptionType);
16247 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16248 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16249 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16250 }
16251
16252 return 0;
16253}
16254
16255
16256/*
16257 * FUNCTION: wlan_hdd_cfg80211_set_ie
16258 * This function is used to parse WPA/RSN IE's.
16259 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016260int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16262 const u8 *ie,
16263#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016265#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016266 size_t ie_len
16267 )
16268{
16269 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16271 const u8 *genie = ie;
16272#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016274#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 v_U16_t remLen = ie_len;
16276#ifdef FEATURE_WLAN_WAPI
16277 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16278 u16 *tmp;
16279 v_U16_t akmsuiteCount;
16280 int *akmlist;
16281#endif
16282 ENTER();
16283
16284 /* clear previous assocAddIE */
16285 pWextState->assocAddIE.length = 0;
16286 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016287 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016288
16289 while (remLen >= 2)
16290 {
16291 v_U16_t eLen = 0;
16292 v_U8_t elementId;
16293 elementId = *genie++;
16294 eLen = *genie++;
16295 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016296
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016297 /* Sanity check on eLen */
16298 if (eLen > remLen) {
16299 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16300 __func__, eLen, elementId);
16301 VOS_ASSERT(0);
16302 return -EINVAL;
16303 }
16304
Arif Hussain6d2a3322013-11-17 19:50:10 -080016305 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016306 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016307
16308 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016309 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016310 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016311 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 -070016312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016313 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016314 "%s: Invalid WPA IE", __func__);
16315 return -EINVAL;
16316 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016317 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 {
16319 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016320 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016321 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016322
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016323 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016324 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016325 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16326 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016327 VOS_ASSERT(0);
16328 return -ENOMEM;
16329 }
16330 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16331 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16332 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016333
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16335 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16336 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16337 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016338 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16339 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016340 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16341 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16342 __func__, eLen);
16343 VOS_ASSERT(0);
16344 return -EINVAL;
16345 }
16346
Jeff Johnson295189b2012-06-20 16:38:30 -070016347 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16348 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16349 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16350 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16351 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16352 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016353 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016354 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016355 {
16356 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016357 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016358 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016359
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016360 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016361 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016362 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16363 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016364 VOS_ASSERT(0);
16365 return -ENOMEM;
16366 }
16367 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16368 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16369 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016370
Jeff Johnson295189b2012-06-20 16:38:30 -070016371 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16372 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16373 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016374#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016375 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16376 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016377 /*Consider WFD IE, only for P2P Client */
16378 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16379 {
16380 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016381 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016383
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016384 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016385 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016386 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16387 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016388 VOS_ASSERT(0);
16389 return -ENOMEM;
16390 }
16391 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16392 // WPS IE + P2P IE + WFD IE
16393 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16394 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016395
Jeff Johnson295189b2012-06-20 16:38:30 -070016396 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16397 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16398 }
16399#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016400 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016401 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016402 HS20_OUI_TYPE_SIZE)) )
16403 {
16404 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016405 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016406 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016407
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016408 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016409 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016410 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16411 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016412 VOS_ASSERT(0);
16413 return -ENOMEM;
16414 }
16415 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16416 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016417
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016418 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16419 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16420 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016421 /* Appending OSEN Information Element in Assiciation Request */
16422 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16423 OSEN_OUI_TYPE_SIZE)) )
16424 {
16425 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16426 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16427 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016428
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016429 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016430 {
16431 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16432 "Need bigger buffer space");
16433 VOS_ASSERT(0);
16434 return -ENOMEM;
16435 }
16436 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16437 pWextState->assocAddIE.length += eLen + 2;
16438
16439 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16440 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16441 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16442 }
16443
Abhishek Singh4322e622015-06-10 15:42:54 +053016444 /* Update only for WPA IE */
16445 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16446 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016447
16448 /* populating as ADDIE in beacon frames */
16449 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016450 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016451 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16452 {
16453 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16454 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16455 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16456 {
16457 hddLog(LOGE,
16458 "Coldn't pass "
16459 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16460 }
16461 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16462 else
16463 hddLog(LOGE,
16464 "Could not pass on "
16465 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16466
16467 /* IBSS mode doesn't contain params->proberesp_ies still
16468 beaconIE's need to be populated in probe response frames */
16469 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16470 {
16471 u16 rem_probe_resp_ie_len = eLen + 2;
16472 u8 probe_rsp_ie_len[3] = {0};
16473 u8 counter = 0;
16474
16475 /* Check Probe Resp Length if it is greater then 255 then
16476 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16477 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16478 not able Store More then 255 bytes into One Variable */
16479
16480 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16481 {
16482 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16483 {
16484 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16485 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16486 }
16487 else
16488 {
16489 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16490 rem_probe_resp_ie_len = 0;
16491 }
16492 }
16493
16494 rem_probe_resp_ie_len = 0;
16495
16496 if (probe_rsp_ie_len[0] > 0)
16497 {
16498 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16499 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16500 (tANI_U8*)(genie - 2),
16501 probe_rsp_ie_len[0], NULL,
16502 eANI_BOOLEAN_FALSE)
16503 == eHAL_STATUS_FAILURE)
16504 {
16505 hddLog(LOGE,
16506 "Could not pass"
16507 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16508 }
16509 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16510 }
16511
16512 if (probe_rsp_ie_len[1] > 0)
16513 {
16514 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16515 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16516 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16517 probe_rsp_ie_len[1], NULL,
16518 eANI_BOOLEAN_FALSE)
16519 == eHAL_STATUS_FAILURE)
16520 {
16521 hddLog(LOGE,
16522 "Could not pass"
16523 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16524 }
16525 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16526 }
16527
16528 if (probe_rsp_ie_len[2] > 0)
16529 {
16530 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16531 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16532 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16533 probe_rsp_ie_len[2], NULL,
16534 eANI_BOOLEAN_FALSE)
16535 == eHAL_STATUS_FAILURE)
16536 {
16537 hddLog(LOGE,
16538 "Could not pass"
16539 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16540 }
16541 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16542 }
16543
16544 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16545 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16546 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16547 {
16548 hddLog(LOGE,
16549 "Could not pass"
16550 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16551 }
16552 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016553 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016554 break;
16555 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016556 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16557 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16558 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16559 VOS_ASSERT(0);
16560 return -EINVAL;
16561 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016562 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16563 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16564 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16565 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16566 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16567 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016568
Abhishek Singhb16f3562016-01-20 11:08:32 +053016569 /* Appending extended capabilities with Interworking or
16570 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016571 *
16572 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016573 * interworkingService or bsstransition bit is set to 1.
16574 * Driver is only interested in interworkingService and
16575 * bsstransition capability from supplicant.
16576 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016577 * required from supplicat, it needs to be handled while
16578 * sending Assoc Req in LIM.
16579 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016580 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016581 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016582 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016583 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016584 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016586 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016587 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016588 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16589 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016590 VOS_ASSERT(0);
16591 return -ENOMEM;
16592 }
16593 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16594 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016595
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016596 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16597 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16598 break;
16599 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016600#ifdef FEATURE_WLAN_WAPI
16601 case WLAN_EID_WAPI:
16602 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016603 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016604 pAdapter->wapi_info.nWapiMode);
16605 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016606 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016607 akmsuiteCount = WPA_GET_LE16(tmp);
16608 tmp = tmp + 1;
16609 akmlist = (int *)(tmp);
16610 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16611 {
16612 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16613 }
16614 else
16615 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016616 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016617 VOS_ASSERT(0);
16618 return -EINVAL;
16619 }
16620
16621 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16622 {
16623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016624 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016625 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016626 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016627 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016628 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016630 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016631 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16632 }
16633 break;
16634#endif
16635 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016636 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016637 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016638 /* when Unknown IE is received we should break and continue
16639 * to the next IE in the buffer instead we were returning
16640 * so changing this to break */
16641 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016642 }
16643 genie += eLen;
16644 remLen -= eLen;
16645 }
16646 EXIT();
16647 return 0;
16648}
16649
16650/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016651 * FUNCTION: hdd_isWPAIEPresent
16652 * Parse the received IE to find the WPA IE
16653 *
16654 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016655static bool hdd_isWPAIEPresent(
16656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16657 const u8 *ie,
16658#else
16659 u8 *ie,
16660#endif
16661 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016662{
16663 v_U8_t eLen = 0;
16664 v_U16_t remLen = ie_len;
16665 v_U8_t elementId = 0;
16666
16667 while (remLen >= 2)
16668 {
16669 elementId = *ie++;
16670 eLen = *ie++;
16671 remLen -= 2;
16672 if (eLen > remLen)
16673 {
16674 hddLog(VOS_TRACE_LEVEL_ERROR,
16675 "%s: IE length is wrong %d", __func__, eLen);
16676 return FALSE;
16677 }
16678 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16679 {
16680 /* OUI - 0x00 0X50 0XF2
16681 WPA Information Element - 0x01
16682 WPA version - 0x01*/
16683 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16684 return TRUE;
16685 }
16686 ie += eLen;
16687 remLen -= eLen;
16688 }
16689 return FALSE;
16690}
16691
16692/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016693 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016694 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016695 * parameters during connect operation.
16696 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016697int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016698 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016699 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016700{
16701 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016702 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016703 ENTER();
16704
16705 /*set wpa version*/
16706 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16707
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016708 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016709 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016710 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 {
16712 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16713 }
16714 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16715 {
16716 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16717 }
16718 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016719
16720 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016721 pWextState->wpaVersion);
16722
16723 /*set authentication type*/
16724 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16725
16726 if (0 > status)
16727 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016728 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016729 "%s: failed to set authentication type ", __func__);
16730 return status;
16731 }
16732
16733 /*set key mgmt type*/
16734 if (req->crypto.n_akm_suites)
16735 {
16736 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16737 if (0 > status)
16738 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016740 __func__);
16741 return status;
16742 }
16743 }
16744
16745 /*set pairwise cipher type*/
16746 if (req->crypto.n_ciphers_pairwise)
16747 {
16748 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16749 req->crypto.ciphers_pairwise[0], true);
16750 if (0 > status)
16751 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016752 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016753 "%s: failed to set unicast cipher type", __func__);
16754 return status;
16755 }
16756 }
16757 else
16758 {
16759 /*Reset previous cipher suite to none*/
16760 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16761 if (0 > status)
16762 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016763 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016764 "%s: failed to set unicast cipher type", __func__);
16765 return status;
16766 }
16767 }
16768
16769 /*set group cipher type*/
16770 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16771 false);
16772
16773 if (0 > status)
16774 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016775 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016776 __func__);
16777 return status;
16778 }
16779
Chet Lanctot186b5732013-03-18 10:26:30 -070016780#ifdef WLAN_FEATURE_11W
16781 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16782#endif
16783
Jeff Johnson295189b2012-06-20 16:38:30 -070016784 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16785 if (req->ie_len)
16786 {
16787 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16788 if ( 0 > status)
16789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016791 __func__);
16792 return status;
16793 }
16794 }
16795
16796 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016797 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016798 {
16799 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16800 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16801 )
16802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016803 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016804 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016807 __func__);
16808 return -EOPNOTSUPP;
16809 }
16810 else
16811 {
16812 u8 key_len = req->key_len;
16813 u8 key_idx = req->key_idx;
16814
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016815 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016816 && (CSR_MAX_NUM_KEY > key_idx)
16817 )
16818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016819 hddLog(VOS_TRACE_LEVEL_INFO,
16820 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016821 __func__, key_idx, key_len);
16822 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016823 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016824 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016825 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016826 (u8)key_len;
16827 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16828 }
16829 }
16830 }
16831 }
16832
16833 return status;
16834}
16835
16836/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016837 * FUNCTION: wlan_hdd_try_disconnect
16838 * This function is used to disconnect from previous
16839 * connection
16840 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016841int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016842{
16843 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016844 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016845 hdd_station_ctx_t *pHddStaCtx;
16846 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016847 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016848
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016849 ret = wlan_hdd_validate_context(pHddCtx);
16850 if (0 != ret)
16851 {
16852 return ret;
16853 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016854 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16855
16856 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16857
16858 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16859 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016860 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016861 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16862 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016863 /* Indicate disconnect to SME so that in-progress connection or preauth
16864 * can be aborted
16865 */
16866 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16867 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016868 spin_lock_bh(&pAdapter->lock_for_active_session);
16869 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16870 {
16871 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16872 }
16873 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016874 hdd_connSetConnectionState(pHddStaCtx,
16875 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016876 /* Issue disconnect to CSR */
16877 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016878 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016879 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016880 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16881 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16882 hddLog(LOG1,
16883 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16884 } else if ( 0 != status ) {
16885 hddLog(LOGE,
16886 FL("csrRoamDisconnect failure, returned %d"),
16887 (int)status );
16888 result = -EINVAL;
16889 goto disconnected;
16890 }
16891 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016892 &pAdapter->disconnect_comp_var,
16893 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016894 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16895 hddLog(LOGE,
16896 "%s: Failed to disconnect, timed out", __func__);
16897 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016898 }
16899 }
16900 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16901 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016902 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016903 &pAdapter->disconnect_comp_var,
16904 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016905 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016906 {
16907 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016908 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016909 }
16910 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016911disconnected:
16912 hddLog(LOG1,
16913 FL("Set HDD connState to eConnectionState_NotConnected"));
16914 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16915 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016916}
16917
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016918/**
16919 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16920 * @adapter: Pointer to the HDD adapter
16921 * @req: Pointer to the structure cfg_connect_params receieved from user space
16922 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053016923 * This function will start reassociation if prev_bssid is set and bssid/
16924 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016925 *
16926 * Return: success if reassociation is happening
16927 * Error code if reassociation is not permitted or not happening
16928 */
16929#ifdef CFG80211_CONNECT_PREV_BSSID
16930static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16931 struct cfg80211_connect_params *req)
16932{
16933 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053016934 const uint8_t *bssid = NULL;
16935 uint16_t channel = 0;
16936
16937 if (req->bssid)
16938 bssid = req->bssid;
16939 else if (req->bssid_hint)
16940 bssid = req->bssid_hint;
16941
16942 if (req->channel)
16943 channel = req->channel->hw_value;
16944 else if (req->channel_hint)
16945 channel = req->channel_hint->hw_value;
16946
16947 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016948 hddLog(VOS_TRACE_LEVEL_INFO,
16949 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053016950 channel, MAC_ADDR_ARRAY(bssid));
16951 status = hdd_reassoc(adapter, bssid, channel,
16952 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016953 }
16954 return status;
16955}
16956#else
16957static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16958 struct cfg80211_connect_params *req)
16959{
16960 return -EPERM;
16961}
16962#endif
16963
Abhishek Singhe3beee22017-07-31 15:35:40 +053016964/**
16965 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16966 * connect in HT20 mode
16967 * @hdd_ctx: hdd context
16968 * @adapter: Pointer to the HDD adapter
16969 * @req: Pointer to the structure cfg_connect_params receieved from user space
16970 *
16971 * This function will check if supplicant has indicated to to connect in HT20
16972 * mode. this is currently applicable only for 2.4Ghz mode only.
16973 * if feature is enabled and supplicant indicate HT20 set
16974 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16975 *
16976 * Return: void
16977 */
16978#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16979static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16980 hdd_adapter_t *adapter,
16981 struct cfg80211_connect_params *req)
16982{
16983 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16984 tCsrRoamProfile *roam_profile;
16985
16986 roam_profile = &wext_state->roamProfile;
16987 roam_profile->force_24ghz_in_ht20 = false;
16988 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16989 !(req->ht_capa.cap_info &
16990 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16991 roam_profile->force_24ghz_in_ht20 = true;
16992
16993 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16994 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16995}
16996#else
16997static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16998 hdd_adapter_t *adapter,
16999 struct cfg80211_connect_params *req)
17000{
17001 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17002 tCsrRoamProfile *roam_profile;
17003
17004 roam_profile = &wext_state->roamProfile;
17005 roam_profile->force_24ghz_in_ht20 = false;
17006}
17007#endif
17008
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017009/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017010 * FUNCTION: __wlan_hdd_cfg80211_connect
17011 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017013static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017014 struct net_device *ndev,
17015 struct cfg80211_connect_params *req
17016 )
17017{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017018 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017019 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17021 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017022 const u8 *bssid_hint = req->bssid_hint;
17023#else
17024 const u8 *bssid_hint = NULL;
17025#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017026 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017028 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017029
17030 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017031
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17033 TRACE_CODE_HDD_CFG80211_CONNECT,
17034 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017035 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017036 "%s: device_mode = %s (%d)", __func__,
17037 hdd_device_modetoString(pAdapter->device_mode),
17038 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017039
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017040 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017041 if (!pHddCtx)
17042 {
17043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17044 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017045 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017046 }
17047
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017048 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017049 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017050 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017051 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017052 }
17053
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017054 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17055 return -EINVAL;
17056
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017057 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17058 if (0 == status)
17059 return status;
17060
Agarwal Ashish51325b52014-06-16 16:50:49 +053017061
Jeff Johnson295189b2012-06-20 16:38:30 -070017062#ifdef WLAN_BTAMP_FEATURE
17063 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017064 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017065 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017066 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017067 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017068 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017069 }
17070#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017071
17072 //If Device Mode is Station Concurrent Sessions Exit BMps
17073 //P2P Mode will be taken care in Open/close adapter
17074 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017075 (vos_concurrent_open_sessions_running())) {
17076 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17077 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017078 }
17079
17080 /*Try disconnecting if already in connected state*/
17081 status = wlan_hdd_try_disconnect(pAdapter);
17082 if ( 0 > status)
17083 {
17084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17085 " connection"));
17086 return -EALREADY;
17087 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017088 /* Check for max concurrent connections after doing disconnect if any*/
17089 if (vos_max_concurrent_connections_reached()) {
17090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17091 return -ECONNREFUSED;
17092 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017093
Jeff Johnson295189b2012-06-20 16:38:30 -070017094 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017095 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017096
17097 if ( 0 > status)
17098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017100 __func__);
17101 return status;
17102 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017103
17104 if (pHddCtx->spoofMacAddr.isEnabled)
17105 {
17106 hddLog(VOS_TRACE_LEVEL_INFO,
17107 "%s: MAC Spoofing enabled ", __func__);
17108 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17109 * to fill TxBds for probe request during SSID scan which may happen
17110 * as part of connect command
17111 */
17112 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17113 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17114 if (status != VOS_STATUS_SUCCESS)
17115 return -ECONNREFUSED;
17116 }
17117
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017118 if (req->channel)
17119 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017120 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017121 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017122
17123 /* Abort if any scan is going on */
17124 status = wlan_hdd_scan_abort(pAdapter);
17125 if (0 != status)
17126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17127
Abhishek Singhe3beee22017-07-31 15:35:40 +053017128 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17129
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017130 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17131 req->ssid_len, req->bssid,
17132 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017133
Sushant Kaushikd7083982015-03-18 14:33:24 +053017134 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017135 {
17136 //ReEnable BMPS if disabled
17137 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17138 (NULL != pHddCtx))
17139 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017140 if (pHddCtx->hdd_wlan_suspended)
17141 {
17142 hdd_set_pwrparams(pHddCtx);
17143 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017144 //ReEnable Bmps and Imps back
17145 hdd_enable_bmps_imps(pHddCtx);
17146 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017148 return status;
17149 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017150 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017151 EXIT();
17152 return status;
17153}
17154
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017155static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17156 struct net_device *ndev,
17157 struct cfg80211_connect_params *req)
17158{
17159 int ret;
17160 vos_ssr_protect(__func__);
17161 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17162 vos_ssr_unprotect(__func__);
17163
17164 return ret;
17165}
Jeff Johnson295189b2012-06-20 16:38:30 -070017166
17167/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017168 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017169 * This function is used to issue a disconnect request to SME
17170 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017171static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017172 struct net_device *dev,
17173 u16 reason
17174 )
17175{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017177 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017178 tCsrRoamProfile *pRoamProfile;
17179 hdd_station_ctx_t *pHddStaCtx;
17180 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017181#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017182 tANI_U8 staIdx;
17183#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017184
Jeff Johnson295189b2012-06-20 16:38:30 -070017185 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017186
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017187 if (!pAdapter) {
17188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17189 return -EINVAL;
17190 }
17191
17192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17193 if (!pHddStaCtx) {
17194 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17195 return -EINVAL;
17196 }
17197
17198 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17199 status = wlan_hdd_validate_context(pHddCtx);
17200 if (0 != status)
17201 {
17202 return status;
17203 }
17204
17205 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17206
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017207 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17208 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17209 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17211 __func__, hdd_device_modetoString(pAdapter->device_mode),
17212 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017213
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017214 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17215 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017216
Jeff Johnson295189b2012-06-20 16:38:30 -070017217 if (NULL != pRoamProfile)
17218 {
17219 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017220 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17221 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017223 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017224 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017225 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017226 switch(reason)
17227 {
17228 case WLAN_REASON_MIC_FAILURE:
17229 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17230 break;
17231
17232 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17233 case WLAN_REASON_DISASSOC_AP_BUSY:
17234 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17235 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17236 break;
17237
17238 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17239 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017240 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017241 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17242 break;
17243
Jeff Johnson295189b2012-06-20 16:38:30 -070017244 default:
17245 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17246 break;
17247 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017248 pScanInfo = &pHddCtx->scan_info;
17249 if (pScanInfo->mScanPending)
17250 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017251 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017252 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017253 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017254 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017255 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017256 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017257#ifdef FEATURE_WLAN_TDLS
17258 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017259 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017260 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017261 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17262 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017263 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017264 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017265 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017267 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017268 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017269 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017270 status = sme_DeleteTdlsPeerSta(
17271 WLAN_HDD_GET_HAL_CTX(pAdapter),
17272 pAdapter->sessionId,
17273 mac);
17274 if (status != eHAL_STATUS_SUCCESS) {
17275 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17276 return -EPERM;
17277 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017278 }
17279 }
17280#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017281
17282 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17283 reasonCode,
17284 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017285 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17286 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017287 {
17288 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017289 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 __func__, (int)status );
17291 return -EINVAL;
17292 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017293 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017294 else
17295 {
17296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17297 "called while in %d state", __func__,
17298 pHddStaCtx->conn_info.connState);
17299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017300 }
17301 else
17302 {
17303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17304 }
17305
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017306 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017307 return status;
17308}
17309
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017310static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17311 struct net_device *dev,
17312 u16 reason
17313 )
17314{
17315 int ret;
17316 vos_ssr_protect(__func__);
17317 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17318 vos_ssr_unprotect(__func__);
17319
17320 return ret;
17321}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017322
Jeff Johnson295189b2012-06-20 16:38:30 -070017323/*
17324 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017325 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017326 * settings in IBSS mode.
17327 */
17328static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017329 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017330 struct cfg80211_ibss_params *params
17331 )
17332{
17333 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017334 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017335 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017336 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17337 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017338
Jeff Johnson295189b2012-06-20 16:38:30 -070017339 ENTER();
17340
17341 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017342 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017343
17344 if (params->ie_len && ( NULL != params->ie) )
17345 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017346 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17347 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017348 {
17349 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17350 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17351 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017352 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017353 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017354 tDot11fIEWPA dot11WPAIE;
17355 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017356 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017357
Wilson Yang00256342013-10-10 23:13:38 -070017358 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017359 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17360 params->ie_len, DOT11F_EID_WPA);
17361 if ( NULL != ie )
17362 {
17363 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017364
17365 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17366 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17367 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17368 return -EINVAL;
17369 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017370 // Unpack the WPA IE
17371 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017372 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017373 &ie[2+4],
17374 ie[1] - 4,
17375 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017376 if (DOT11F_FAILED(ret))
17377 {
17378 hddLog(LOGE,
17379 FL("unpack failed status:(0x%08x)"),
17380 ret);
17381 return -EINVAL;
17382 }
17383
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017384 /*Extract the multicast cipher, the encType for unicast
17385 cipher for wpa-none is none*/
17386 encryptionType =
17387 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017389 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017390
Jeff Johnson295189b2012-06-20 16:38:30 -070017391 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17392
17393 if (0 > status)
17394 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017395 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017396 __func__);
17397 return status;
17398 }
17399 }
17400
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017401 pWextState->roamProfile.AuthType.authType[0] =
17402 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017403 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017404 if (params->privacy)
17405 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017406 /* Security enabled IBSS, At this time there is no information available
17407 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017408 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017409 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017410 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017411 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017412 *enable privacy bit in beacons */
17413
17414 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17415 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017416 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17417 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017418 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17419 pWextState->roamProfile.EncryptionType.numEntries = 1;
17420 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017421 return status;
17422}
17423
17424/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017425 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017426 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017427 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017428static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017429 struct net_device *dev,
17430 struct cfg80211_ibss_params *params
17431 )
17432{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017433 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017434 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17435 tCsrRoamProfile *pRoamProfile;
17436 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017437 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17438 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017439 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017440
17441 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017442
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017443 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17444 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17445 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017446 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017447 "%s: device_mode = %s (%d)", __func__,
17448 hdd_device_modetoString(pAdapter->device_mode),
17449 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017450
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017451 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017452 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017453 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017454 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017455 }
17456
17457 if (NULL == pWextState)
17458 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017459 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017460 __func__);
17461 return -EIO;
17462 }
17463
Agarwal Ashish51325b52014-06-16 16:50:49 +053017464 if (vos_max_concurrent_connections_reached()) {
17465 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17466 return -ECONNREFUSED;
17467 }
17468
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017469 /*Try disconnecting if already in connected state*/
17470 status = wlan_hdd_try_disconnect(pAdapter);
17471 if ( 0 > status)
17472 {
17473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17474 " IBSS connection"));
17475 return -EALREADY;
17476 }
17477
Jeff Johnson295189b2012-06-20 16:38:30 -070017478 pRoamProfile = &pWextState->roamProfile;
17479
17480 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17481 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017482 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017483 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017484 return -EINVAL;
17485 }
17486
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017487 /* BSSID is provided by upper layers hence no need to AUTO generate */
17488 if (NULL != params->bssid) {
17489 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17490 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17491 hddLog (VOS_TRACE_LEVEL_ERROR,
17492 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17493 return -EIO;
17494 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017495 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017496 }
krunal sonie9002db2013-11-25 14:24:17 -080017497 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17498 {
17499 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17500 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17501 {
17502 hddLog (VOS_TRACE_LEVEL_ERROR,
17503 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17504 return -EIO;
17505 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017506
17507 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017508 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017509 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017510 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017511
Jeff Johnson295189b2012-06-20 16:38:30 -070017512 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017513 if (NULL !=
17514#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17515 params->chandef.chan)
17516#else
17517 params->channel)
17518#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 {
17520 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017521 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17522 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17523 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17524 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017525
17526 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017527 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017528 ieee80211_frequency_to_channel(
17529#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17530 params->chandef.chan->center_freq);
17531#else
17532 params->channel->center_freq);
17533#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017534
17535 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17536 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017537 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17539 __func__);
17540 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017541 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017542
17543 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017544 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017545 if (channelNum == validChan[indx])
17546 {
17547 break;
17548 }
17549 }
17550 if (indx >= numChans)
17551 {
17552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017553 __func__, channelNum);
17554 return -EINVAL;
17555 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017556 /* Set the Operational Channel */
17557 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17558 channelNum);
17559 pRoamProfile->ChannelInfo.numOfChannels = 1;
17560 pHddStaCtx->conn_info.operationChannel = channelNum;
17561 pRoamProfile->ChannelInfo.ChannelList =
17562 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017563 }
17564
17565 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017566 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017567 if (status < 0)
17568 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017570 __func__);
17571 return status;
17572 }
17573
17574 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017575 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017576 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017577 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017578
17579 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017582 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017583 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017584}
17585
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017586static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17587 struct net_device *dev,
17588 struct cfg80211_ibss_params *params
17589 )
17590{
17591 int ret = 0;
17592
17593 vos_ssr_protect(__func__);
17594 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17595 vos_ssr_unprotect(__func__);
17596
17597 return ret;
17598}
17599
Jeff Johnson295189b2012-06-20 16:38:30 -070017600/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017601 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017602 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017603 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017604static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 struct net_device *dev
17606 )
17607{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017609 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17610 tCsrRoamProfile *pRoamProfile;
17611 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017612 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017613 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017614#ifdef WLAN_FEATURE_RMC
17615 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017617
17618 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017619
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17621 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17622 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017623 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017624 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017625 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017626 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017627 }
17628
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17630 hdd_device_modetoString(pAdapter->device_mode),
17631 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017632 if (NULL == pWextState)
17633 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017634 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017635 __func__);
17636 return -EIO;
17637 }
17638
17639 pRoamProfile = &pWextState->roamProfile;
17640
17641 /* Issue disconnect only if interface type is set to IBSS */
17642 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17643 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017644 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017645 __func__);
17646 return -EINVAL;
17647 }
17648
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017649#ifdef WLAN_FEATURE_RMC
17650 /* Clearing add IE of beacon */
17651 if (ccmCfgSetStr(pHddCtx->hHal,
17652 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17653 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17654 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17655 {
17656 hddLog (VOS_TRACE_LEVEL_ERROR,
17657 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17658 return -EINVAL;
17659 }
17660 if (ccmCfgSetInt(pHddCtx->hHal,
17661 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17662 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17663 {
17664 hddLog (VOS_TRACE_LEVEL_ERROR,
17665 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17666 __func__);
17667 return -EINVAL;
17668 }
17669
17670 // Reset WNI_CFG_PROBE_RSP Flags
17671 wlan_hdd_reset_prob_rspies(pAdapter);
17672
17673 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17674 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17675 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17676 {
17677 hddLog (VOS_TRACE_LEVEL_ERROR,
17678 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17679 __func__);
17680 return -EINVAL;
17681 }
17682#endif
17683
Jeff Johnson295189b2012-06-20 16:38:30 -070017684 /* Issue Disconnect request */
17685 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017686 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17687 pAdapter->sessionId,
17688 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17689 if (!HAL_STATUS_SUCCESS(hal_status)) {
17690 hddLog(LOGE,
17691 FL("sme_RoamDisconnect failed hal_status(%d)"),
17692 hal_status);
17693 return -EAGAIN;
17694 }
17695 status = wait_for_completion_timeout(
17696 &pAdapter->disconnect_comp_var,
17697 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17698 if (!status) {
17699 hddLog(LOGE,
17700 FL("wait on disconnect_comp_var failed"));
17701 return -ETIMEDOUT;
17702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017704 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017705 return 0;
17706}
17707
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017708static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17709 struct net_device *dev
17710 )
17711{
17712 int ret = 0;
17713
17714 vos_ssr_protect(__func__);
17715 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17716 vos_ssr_unprotect(__func__);
17717
17718 return ret;
17719}
17720
Jeff Johnson295189b2012-06-20 16:38:30 -070017721/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017722 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017723 * This function is used to set the phy parameters
17724 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17725 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017726static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017727 u32 changed)
17728{
17729 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17730 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017731 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017732
17733 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017734
17735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017736 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17737 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017739 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017740 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017742 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017743 }
17744
Jeff Johnson295189b2012-06-20 16:38:30 -070017745 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17746 {
17747 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17748 WNI_CFG_RTS_THRESHOLD_STAMAX :
17749 wiphy->rts_threshold;
17750
17751 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017752 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017754 hddLog(VOS_TRACE_LEVEL_ERROR,
17755 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017756 __func__, rts_threshold);
17757 return -EINVAL;
17758 }
17759
17760 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17761 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017762 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017763 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017764 hddLog(VOS_TRACE_LEVEL_ERROR,
17765 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017766 __func__, rts_threshold);
17767 return -EIO;
17768 }
17769
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017770 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017771 rts_threshold);
17772 }
17773
17774 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17775 {
17776 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17777 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17778 wiphy->frag_threshold;
17779
17780 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017781 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017783 hddLog(VOS_TRACE_LEVEL_ERROR,
17784 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017785 frag_threshold);
17786 return -EINVAL;
17787 }
17788
17789 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17790 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017791 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017792 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017793 hddLog(VOS_TRACE_LEVEL_ERROR,
17794 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017795 __func__, frag_threshold);
17796 return -EIO;
17797 }
17798
17799 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17800 frag_threshold);
17801 }
17802
17803 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17804 || (changed & WIPHY_PARAM_RETRY_LONG))
17805 {
17806 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17807 wiphy->retry_short :
17808 wiphy->retry_long;
17809
17810 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17811 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17812 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017814 __func__, retry_value);
17815 return -EINVAL;
17816 }
17817
17818 if (changed & WIPHY_PARAM_RETRY_SHORT)
17819 {
17820 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17821 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017822 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017824 hddLog(VOS_TRACE_LEVEL_ERROR,
17825 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017826 __func__, retry_value);
17827 return -EIO;
17828 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017829 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017830 __func__, retry_value);
17831 }
17832 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17833 {
17834 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17835 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017836 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017837 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017838 hddLog(VOS_TRACE_LEVEL_ERROR,
17839 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017840 __func__, retry_value);
17841 return -EIO;
17842 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017843 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017844 __func__, retry_value);
17845 }
17846 }
17847
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017848 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017849 return 0;
17850}
17851
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017852static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17853 u32 changed)
17854{
17855 int ret;
17856
17857 vos_ssr_protect(__func__);
17858 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17859 vos_ssr_unprotect(__func__);
17860
17861 return ret;
17862}
17863
Jeff Johnson295189b2012-06-20 16:38:30 -070017864/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017865 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017866 * This function is used to set the txpower
17867 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017868static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017869#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17870 struct wireless_dev *wdev,
17871#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017872#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017873 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017874#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017875 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017876#endif
17877 int dbm)
17878{
17879 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017880 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017881 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17882 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017883 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017884
17885 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017886
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017887 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17888 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17889 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017890 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017891 if (0 != status)
17892 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017893 return status;
17894 }
17895
17896 hHal = pHddCtx->hHal;
17897
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017898 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17899 dbm, ccmCfgSetCallback,
17900 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017902 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017903 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17904 return -EIO;
17905 }
17906
17907 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17908 dbm);
17909
17910 switch(type)
17911 {
17912 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17913 /* Fall through */
17914 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17915 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17918 __func__);
17919 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017920 }
17921 break;
17922 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017924 __func__);
17925 return -EOPNOTSUPP;
17926 break;
17927 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17929 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017930 return -EIO;
17931 }
17932
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017933 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017934 return 0;
17935}
17936
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017937static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17938#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17939 struct wireless_dev *wdev,
17940#endif
17941#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17942 enum tx_power_setting type,
17943#else
17944 enum nl80211_tx_power_setting type,
17945#endif
17946 int dbm)
17947{
17948 int ret;
17949 vos_ssr_protect(__func__);
17950 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17951#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17952 wdev,
17953#endif
17954#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17955 type,
17956#else
17957 type,
17958#endif
17959 dbm);
17960 vos_ssr_unprotect(__func__);
17961
17962 return ret;
17963}
17964
Jeff Johnson295189b2012-06-20 16:38:30 -070017965/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017966 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017967 * This function is used to read the txpower
17968 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017969static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017970#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17971 struct wireless_dev *wdev,
17972#endif
17973 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017974{
17975
17976 hdd_adapter_t *pAdapter;
17977 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017978 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017979
Jeff Johnsone7245742012-09-05 17:12:55 -070017980 ENTER();
17981
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017982 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017983 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017985 *dbm = 0;
17986 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017987 }
17988
Jeff Johnson295189b2012-06-20 16:38:30 -070017989 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17990 if (NULL == pAdapter)
17991 {
17992 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17993 return -ENOENT;
17994 }
17995
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017996 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17997 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17998 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017999 wlan_hdd_get_classAstats(pAdapter);
18000 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18001
Jeff Johnsone7245742012-09-05 17:12:55 -070018002 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018003 return 0;
18004}
18005
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018006static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18007#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18008 struct wireless_dev *wdev,
18009#endif
18010 int *dbm)
18011{
18012 int ret;
18013
18014 vos_ssr_protect(__func__);
18015 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18016#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18017 wdev,
18018#endif
18019 dbm);
18020 vos_ssr_unprotect(__func__);
18021
18022 return ret;
18023}
18024
Dustin Brown8c1d4092017-07-28 18:08:01 +053018025/*
18026 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18027 * @stats: summary stats to use as a source
18028 * @info: kernel station_info struct to use as a destination
18029 *
18030 * Return: None
18031 */
18032static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18033 struct station_info *info)
18034{
18035 int i;
18036
18037 info->rx_packets = stats->rx_frm_cnt;
18038 info->tx_packets = 0;
18039 info->tx_retries = 0;
18040 info->tx_failed = 0;
18041
18042 for (i = 0; i < 4; ++i) {
18043 info->tx_packets += stats->tx_frm_cnt[i];
18044 info->tx_retries += stats->multiple_retry_cnt[i];
18045 info->tx_failed += stats->fail_cnt[i];
18046 }
18047
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018048#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18049 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018050 info->filled |= STATION_INFO_TX_PACKETS |
18051 STATION_INFO_TX_RETRIES |
18052 STATION_INFO_TX_FAILED |
18053 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018054#else
18055 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18056 BIT(NL80211_STA_INFO_TX_RETRIES) |
18057 BIT(NL80211_STA_INFO_TX_FAILED) |
18058 BIT(NL80211_STA_INFO_RX_PACKETS);
18059#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018060}
18061
18062/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018063 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18064 * @adapter: sap adapter pointer
18065 * @staid: station id of the client
18066 * @rssi: rssi value to fill
18067 *
18068 * Return: None
18069 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018070void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018071wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18072{
18073 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18074
18075 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18076}
18077
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018078#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18079 !defined(WITH_BACKPORTS)
18080static inline void wlan_hdd_fill_station_info_signal(struct station_info
18081 *sinfo)
18082{
18083 sinfo->filled |= STATION_INFO_SIGNAL;
18084}
18085#else
18086static inline void wlan_hdd_fill_station_info_signal(struct station_info
18087 *sinfo)
18088{
18089 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18090}
18091#endif
18092
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018093/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018094 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18095 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018096 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018097 * @info: kernel station_info struct to populate
18098 *
18099 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18100 * support "station dump" and "station get" for SAP vdevs, even though they
18101 * aren't technically stations.
18102 *
18103 * Return: errno
18104 */
18105static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018106wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18108 const u8* mac,
18109#else
18110 u8* mac,
18111#endif
18112 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018113{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018114 v_MACADDR_t *peerMacAddr;
18115 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018116 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018117 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018118
18119 status = wlan_hdd_get_station_stats(adapter);
18120 if (!VOS_IS_STATUS_SUCCESS(status)) {
18121 hddLog(VOS_TRACE_LEVEL_ERROR,
18122 "Failed to get SAP stats; status:%d", status);
18123 return 0;
18124 }
18125
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018126 peerMacAddr = (v_MACADDR_t *)mac;
18127 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18128 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18129 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18130
18131 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18132 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018133 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018134 }
18135
Dustin Brown8c1d4092017-07-28 18:08:01 +053018136 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18137
18138 return 0;
18139}
18140
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018141static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018142#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18143 const u8* mac,
18144#else
18145 u8* mac,
18146#endif
18147 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018148{
18149 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18150 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18151 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018152 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018153
18154 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18155 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018156
18157 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18158 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18159 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18160 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18161 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18162 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18163 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018164 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018165 tANI_U16 myRate;
18166 tANI_U16 currentRate = 0;
18167 tANI_U8 maxSpeedMCS = 0;
18168 tANI_U8 maxMCSIdx = 0;
18169 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018170 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018171 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018172 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018173
Leo Chang6f8870f2013-03-26 18:11:36 -070018174#ifdef WLAN_FEATURE_11AC
18175 tANI_U32 vht_mcs_map;
18176 eDataRate11ACMaxMcs vhtMaxMcs;
18177#endif /* WLAN_FEATURE_11AC */
18178
Jeff Johnsone7245742012-09-05 17:12:55 -070018179 ENTER();
18180
Dustin Brown8c1d4092017-07-28 18:08:01 +053018181 status = wlan_hdd_validate_context(pHddCtx);
18182 if (0 != status)
18183 {
18184 return status;
18185 }
18186
18187 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018188 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018189
Jeff Johnson295189b2012-06-20 16:38:30 -070018190 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18191 (0 == ssidlen))
18192 {
18193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18194 " Invalid ssidlen, %d", __func__, ssidlen);
18195 /*To keep GUI happy*/
18196 return 0;
18197 }
18198
Mukul Sharma811205f2014-07-09 21:07:30 +053018199 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18200 {
18201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18202 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018203 /* return a cached value */
18204 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018205 return 0;
18206 }
18207
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018208 wlan_hdd_get_station_stats(pAdapter);
18209 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018210
Kiet Lam3b17fc82013-09-27 05:24:08 +053018211 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018212 wlan_hdd_get_snr(pAdapter, &snr);
18213 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018214 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018215 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018216 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018217 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018218
c_hpothu09f19542014-05-30 21:53:31 +053018219 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018220 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18221 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018222 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018223 {
18224 rate_flags = pAdapter->maxRateFlags;
18225 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018226
Jeff Johnson295189b2012-06-20 16:38:30 -070018227 //convert to the UI units of 100kbps
18228 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18229
18230#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018231 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 -070018232 sinfo->signal,
18233 pCfg->reportMaxLinkSpeed,
18234 myRate,
18235 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018236 (int) pCfg->linkSpeedRssiMid,
18237 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018238 (int) rate_flags,
18239 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018240#endif //LINKSPEED_DEBUG_ENABLED
18241
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018242#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18243 /* assume basic BW. anything else will override this later */
18244 sinfo->txrate.bw = RATE_INFO_BW_20;
18245#endif
18246
Jeff Johnson295189b2012-06-20 16:38:30 -070018247 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18248 {
18249 // we do not want to necessarily report the current speed
18250 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18251 {
18252 // report the max possible speed
18253 rssidx = 0;
18254 }
18255 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18256 {
18257 // report the max possible speed with RSSI scaling
18258 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18259 {
18260 // report the max possible speed
18261 rssidx = 0;
18262 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018263 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018264 {
18265 // report middle speed
18266 rssidx = 1;
18267 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018268 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18269 {
18270 // report middle speed
18271 rssidx = 2;
18272 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018273 else
18274 {
18275 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018276 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018277 }
18278 }
18279 else
18280 {
18281 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18282 hddLog(VOS_TRACE_LEVEL_ERROR,
18283 "%s: Invalid value for reportMaxLinkSpeed: %u",
18284 __func__, pCfg->reportMaxLinkSpeed);
18285 rssidx = 0;
18286 }
18287
18288 maxRate = 0;
18289
18290 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018291 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18292 OperationalRates, &ORLeng))
18293 {
18294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18295 /*To keep GUI happy*/
18296 return 0;
18297 }
18298
Jeff Johnson295189b2012-06-20 16:38:30 -070018299 for (i = 0; i < ORLeng; i++)
18300 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018301 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018302 {
18303 /* Validate Rate Set */
18304 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18305 {
18306 currentRate = supported_data_rate[j].supported_rate[rssidx];
18307 break;
18308 }
18309 }
18310 /* Update MAX rate */
18311 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18312 }
18313
18314 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018315 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18316 ExtendedRates, &ERLeng))
18317 {
18318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18319 /*To keep GUI happy*/
18320 return 0;
18321 }
18322
Jeff Johnson295189b2012-06-20 16:38:30 -070018323 for (i = 0; i < ERLeng; i++)
18324 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018325 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018326 {
18327 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18328 {
18329 currentRate = supported_data_rate[j].supported_rate[rssidx];
18330 break;
18331 }
18332 }
18333 /* Update MAX rate */
18334 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18335 }
c_hpothu79aab322014-07-14 21:11:01 +053018336
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018337 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018338 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018339 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018340 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018341 {
c_hpothu79aab322014-07-14 21:11:01 +053018342 if (rate_flags & eHAL_TX_RATE_VHT80)
18343 mode = 2;
18344 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18345 mode = 1;
18346 else
18347 mode = 0;
18348
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018349 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18350 MCSRates, &MCSLeng))
18351 {
18352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18353 /*To keep GUI happy*/
18354 return 0;
18355 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018356 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018357#ifdef WLAN_FEATURE_11AC
18358 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018359 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018360 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018361 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018362 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018363 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018364 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018365 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018366 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018367 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018368 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018369 maxMCSIdx = 7;
18370 }
18371 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18372 {
18373 maxMCSIdx = 8;
18374 }
18375 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18376 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018377 //VHT20 is supporting 0~8
18378 if (rate_flags & eHAL_TX_RATE_VHT20)
18379 maxMCSIdx = 8;
18380 else
18381 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018382 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018383
c_hpothu79aab322014-07-14 21:11:01 +053018384 if (0 != rssidx)/*check for scaled */
18385 {
18386 //get middle rate MCS index if rssi=1/2
18387 for (i=0; i <= maxMCSIdx; i++)
18388 {
18389 if (sinfo->signal <= rssiMcsTbl[mode][i])
18390 {
18391 maxMCSIdx = i;
18392 break;
18393 }
18394 }
18395 }
18396
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018397 if (rate_flags & eHAL_TX_RATE_VHT80)
18398 {
18399 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18400 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18401 }
18402 else if (rate_flags & eHAL_TX_RATE_VHT40)
18403 {
18404 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18405 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18406 }
18407 else if (rate_flags & eHAL_TX_RATE_VHT20)
18408 {
18409 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18410 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18411 }
18412
Leo Chang6f8870f2013-03-26 18:11:36 -070018413 maxSpeedMCS = 1;
18414 if (currentRate > maxRate)
18415 {
18416 maxRate = currentRate;
18417 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018418
Leo Chang6f8870f2013-03-26 18:11:36 -070018419 }
18420 else
18421#endif /* WLAN_FEATURE_11AC */
18422 {
18423 if (rate_flags & eHAL_TX_RATE_HT40)
18424 {
18425 rateFlag |= 1;
18426 }
18427 if (rate_flags & eHAL_TX_RATE_SGI)
18428 {
18429 rateFlag |= 2;
18430 }
18431
Girish Gowli01abcee2014-07-31 20:18:55 +053018432 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018433 if (rssidx == 1 || rssidx == 2)
18434 {
18435 //get middle rate MCS index if rssi=1/2
18436 for (i=0; i <= 7; i++)
18437 {
18438 if (sinfo->signal <= rssiMcsTbl[mode][i])
18439 {
18440 temp = i+1;
18441 break;
18442 }
18443 }
18444 }
c_hpothu79aab322014-07-14 21:11:01 +053018445
18446 for (i = 0; i < MCSLeng; i++)
18447 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018448 for (j = 0; j < temp; j++)
18449 {
18450 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18451 {
18452 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018453 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018454 break;
18455 }
18456 }
18457 if ((j < temp) && (currentRate > maxRate))
18458 {
18459 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018460 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018461 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018462 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018463 }
18464 }
18465
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018466 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18467 {
18468 maxRate = myRate;
18469 maxSpeedMCS = 1;
18470 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018472 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018473 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018474 {
18475 maxRate = myRate;
18476 if (rate_flags & eHAL_TX_RATE_LEGACY)
18477 {
18478 maxSpeedMCS = 0;
18479 }
18480 else
18481 {
18482 maxSpeedMCS = 1;
18483 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18484 }
18485 }
18486
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018487 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018488 {
18489 sinfo->txrate.legacy = maxRate;
18490#ifdef LINKSPEED_DEBUG_ENABLED
18491 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18492#endif //LINKSPEED_DEBUG_ENABLED
18493 }
18494 else
18495 {
18496 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018497#ifdef WLAN_FEATURE_11AC
18498 sinfo->txrate.nss = 1;
18499 if (rate_flags & eHAL_TX_RATE_VHT80)
18500 {
18501 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018502#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18503 defined(WITH_BACKPORTS)
18504 sinfo->txrate.bw = RATE_INFO_BW_80;
18505#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018506 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018507#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018508 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018509 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018510 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018511 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18513 defined(WITH_BACKPORTS)
18514 sinfo->txrate.bw = RATE_INFO_BW_40;
18515#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018516 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018517#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018518 }
18519 else if (rate_flags & eHAL_TX_RATE_VHT20)
18520 {
18521 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18522 }
18523#endif /* WLAN_FEATURE_11AC */
18524 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18525 {
18526 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18527 if (rate_flags & eHAL_TX_RATE_HT40)
18528 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018529#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18530 defined(WITH_BACKPORTS)
18531 sinfo->txrate.bw = RATE_INFO_BW_40;
18532#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018533 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018534#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018535 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018536 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018537 if (rate_flags & eHAL_TX_RATE_SGI)
18538 {
18539 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18540 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018541
Jeff Johnson295189b2012-06-20 16:38:30 -070018542#ifdef LINKSPEED_DEBUG_ENABLED
18543 pr_info("Reporting MCS rate %d flags %x\n",
18544 sinfo->txrate.mcs,
18545 sinfo->txrate.flags );
18546#endif //LINKSPEED_DEBUG_ENABLED
18547 }
18548 }
18549 else
18550 {
18551 // report current rate instead of max rate
18552
18553 if (rate_flags & eHAL_TX_RATE_LEGACY)
18554 {
18555 //provide to the UI in units of 100kbps
18556 sinfo->txrate.legacy = myRate;
18557#ifdef LINKSPEED_DEBUG_ENABLED
18558 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18559#endif //LINKSPEED_DEBUG_ENABLED
18560 }
18561 else
18562 {
18563 //must be MCS
18564 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018565#ifdef WLAN_FEATURE_11AC
18566 sinfo->txrate.nss = 1;
18567 if (rate_flags & eHAL_TX_RATE_VHT80)
18568 {
18569 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18570 }
18571 else
18572#endif /* WLAN_FEATURE_11AC */
18573 {
18574 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18575 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018576 if (rate_flags & eHAL_TX_RATE_SGI)
18577 {
18578 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18579 }
18580 if (rate_flags & eHAL_TX_RATE_HT40)
18581 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018582#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18583 defined(WITH_BACKPORTS)
18584 sinfo->txrate.bw = RATE_INFO_BW_40;
18585#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018586 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018587#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018588 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018589#ifdef WLAN_FEATURE_11AC
18590 else if (rate_flags & eHAL_TX_RATE_VHT80)
18591 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18593 defined(WITH_BACKPORTS)
18594 sinfo->txrate.bw = RATE_INFO_BW_80;
18595#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018596 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018597#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018598 }
18599#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018600#ifdef LINKSPEED_DEBUG_ENABLED
18601 pr_info("Reporting actual MCS rate %d flags %x\n",
18602 sinfo->txrate.mcs,
18603 sinfo->txrate.flags );
18604#endif //LINKSPEED_DEBUG_ENABLED
18605 }
18606 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018607
18608#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18609 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018610 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018611#else
18612 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18613#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018614
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018615 sinfo->tx_packets =
18616 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18617 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18618 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18619 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18620
18621 sinfo->tx_retries =
18622 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18623 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18624 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18625 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18626
18627 sinfo->tx_failed =
18628 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18629 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18630 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18631 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18632
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018633#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18634 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018635 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018636 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018637 STATION_INFO_TX_PACKETS |
18638 STATION_INFO_TX_RETRIES |
18639 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018640#else
18641 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18642 BIT(NL80211_STA_INFO_TX_PACKETS) |
18643 BIT(NL80211_STA_INFO_TX_RETRIES) |
18644 BIT(NL80211_STA_INFO_TX_FAILED);
18645#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018646
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018647 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018648
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018649 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18650 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018651 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18652 &sinfo->txrate, sizeof(sinfo->txrate));
18653
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018654 if (rate_flags & eHAL_TX_RATE_LEGACY)
18655 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18656 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18657 sinfo->rx_packets);
18658 else
18659 hddLog(LOG1,
18660 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18661 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18662 sinfo->tx_packets, sinfo->rx_packets);
18663
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018664 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18665 TRACE_CODE_HDD_CFG80211_GET_STA,
18666 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018667 EXIT();
18668 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018669}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18671static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18672 const u8* mac, struct station_info *sinfo)
18673#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018674static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18675 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018676#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018677{
18678 int ret;
18679
18680 vos_ssr_protect(__func__);
18681 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18682 vos_ssr_unprotect(__func__);
18683
18684 return ret;
18685}
18686
18687static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018688 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018689{
18690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018691 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018692 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018693 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018694
Jeff Johnsone7245742012-09-05 17:12:55 -070018695 ENTER();
18696
Jeff Johnson295189b2012-06-20 16:38:30 -070018697 if (NULL == pAdapter)
18698 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018700 return -ENODEV;
18701 }
18702
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018703 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18704 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18705 pAdapter->sessionId, timeout));
18706
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018707 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018708 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018709 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018710 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018711 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018712 }
18713
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018714 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18715 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18716 (pHddCtx->cfg_ini->fhostArpOffload) &&
18717 (eConnectionState_Associated ==
18718 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18719 {
Amar Singhald53568e2013-09-26 11:03:45 -070018720
18721 hddLog(VOS_TRACE_LEVEL_INFO,
18722 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018723 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018724 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18725 {
18726 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018727 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018728 __func__, vos_status);
18729 }
18730 }
18731
Jeff Johnson295189b2012-06-20 16:38:30 -070018732 /**The get power cmd from the supplicant gets updated by the nl only
18733 *on successful execution of the function call
18734 *we are oppositely mapped w.r.t mode in the driver
18735 **/
18736 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18737
18738 if (VOS_STATUS_E_FAILURE == vos_status)
18739 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18741 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018742 return -EINVAL;
18743 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018744 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018745 return 0;
18746}
18747
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018748static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18749 struct net_device *dev, bool mode, int timeout)
18750{
18751 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018752
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018753 vos_ssr_protect(__func__);
18754 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18755 vos_ssr_unprotect(__func__);
18756
18757 return ret;
18758}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018759
Jeff Johnson295189b2012-06-20 16:38:30 -070018760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018761static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18762 struct net_device *netdev,
18763 u8 key_index)
18764{
18765 ENTER();
18766 return 0;
18767}
18768
Jeff Johnson295189b2012-06-20 16:38:30 -070018769static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018770 struct net_device *netdev,
18771 u8 key_index)
18772{
18773 int ret;
18774 vos_ssr_protect(__func__);
18775 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18776 vos_ssr_unprotect(__func__);
18777 return ret;
18778}
18779#endif //LINUX_VERSION_CODE
18780
18781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18782static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18783 struct net_device *dev,
18784 struct ieee80211_txq_params *params)
18785{
18786 ENTER();
18787 return 0;
18788}
18789#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18790static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18791 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018792{
Jeff Johnsone7245742012-09-05 17:12:55 -070018793 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018794 return 0;
18795}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018796#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018797
18798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18799static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018800 struct net_device *dev,
18801 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018802{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018803 int ret;
18804
18805 vos_ssr_protect(__func__);
18806 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18807 vos_ssr_unprotect(__func__);
18808 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018809}
18810#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18811static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18812 struct ieee80211_txq_params *params)
18813{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018814 int ret;
18815
18816 vos_ssr_protect(__func__);
18817 ret = __wlan_hdd_set_txq_params(wiphy, params);
18818 vos_ssr_unprotect(__func__);
18819 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018820}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018822
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018823static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018824 struct net_device *dev,
18825 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018826{
18827 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018828 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018829 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018830 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018831 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018832 v_CONTEXT_t pVosContext = NULL;
18833 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018834
Jeff Johnsone7245742012-09-05 17:12:55 -070018835 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018836
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018837 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018838 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018840 return -EINVAL;
18841 }
18842
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018843 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18844 TRACE_CODE_HDD_CFG80211_DEL_STA,
18845 pAdapter->sessionId, pAdapter->device_mode));
18846
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018847 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18848 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018849 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018850 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018851 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018852 }
18853
Jeff Johnson295189b2012-06-20 16:38:30 -070018854 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018855 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018856 )
18857 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018858 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18859 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18860 if(pSapCtx == NULL){
18861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18862 FL("psapCtx is NULL"));
18863 return -ENOENT;
18864 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018865 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18866 {
18867 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18868 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18869 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18870 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018871 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018872 {
18873 v_U16_t i;
18874 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18875 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018876 if ((pSapCtx->aStaInfo[i].isUsed) &&
18877 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018878 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018879 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018880 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018881 ETHER_ADDR_LEN);
18882
Jeff Johnson295189b2012-06-20 16:38:30 -070018883 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018884 "%s: Delete STA with MAC::"
18885 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018886 __func__,
18887 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18888 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018889 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018890 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018891 }
18892 }
18893 }
18894 else
18895 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018896
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018897 vos_status = hdd_softap_GetStaId(pAdapter,
18898 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018899 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18900 {
18901 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018902 "%s: Skip this DEL STA as this is not used::"
18903 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018904 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018905 return -ENOENT;
18906 }
18907
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018908 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018909 {
18910 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018911 "%s: Skip this DEL STA as deauth is in progress::"
18912 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018913 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018914 return -ENOENT;
18915 }
18916
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018917 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018918
Jeff Johnson295189b2012-06-20 16:38:30 -070018919 hddLog(VOS_TRACE_LEVEL_INFO,
18920 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018921 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018922 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018923 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018924
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018925 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018926 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18927 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018928 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018929 hddLog(VOS_TRACE_LEVEL_INFO,
18930 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018931 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018932 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018933 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018934 return -ENOENT;
18935 }
18936
Jeff Johnson295189b2012-06-20 16:38:30 -070018937 }
18938 }
18939
18940 EXIT();
18941
18942 return 0;
18943}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018944
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018945#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018946int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018947 struct net_device *dev,
18948 struct station_del_parameters *param)
18949#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018951int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018952 struct net_device *dev, const u8 *mac)
18953#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018954int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018955 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018956#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018957#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018958{
18959 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018960 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018961
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018962 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018963
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018964#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018965 if (NULL == param) {
18966 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018967 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018968 return -EINVAL;
18969 }
18970
18971 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18972 param->subtype, &delStaParams);
18973
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018974#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018975 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018976 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018977#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018978 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18979
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018980 vos_ssr_unprotect(__func__);
18981
18982 return ret;
18983}
18984
18985static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018986 struct net_device *dev,
18987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18988 const u8 *mac,
18989#else
18990 u8 *mac,
18991#endif
18992 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018993{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018994 hdd_adapter_t *pAdapter;
18995 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018996 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018997#ifdef FEATURE_WLAN_TDLS
18998 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018999
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019000 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019001
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019002 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19003 if (NULL == pAdapter)
19004 {
19005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19006 "%s: Adapter is NULL",__func__);
19007 return -EINVAL;
19008 }
19009 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19010 status = wlan_hdd_validate_context(pHddCtx);
19011 if (0 != status)
19012 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019013 return status;
19014 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019015
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019016 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19017 TRACE_CODE_HDD_CFG80211_ADD_STA,
19018 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019019 mask = params->sta_flags_mask;
19020
19021 set = params->sta_flags_set;
19022
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019024 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19025 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019026
19027 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19028 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019029 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019030 }
19031 }
19032#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019033 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019034 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019035}
19036
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019037#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19038static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19039 struct net_device *dev, const u8 *mac,
19040 struct station_parameters *params)
19041#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019042static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19043 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019044#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019045{
19046 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019047
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019048 vos_ssr_protect(__func__);
19049 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19050 vos_ssr_unprotect(__func__);
19051
19052 return ret;
19053}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019054#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019055
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019056static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019057 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019058{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019059 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19060 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019061 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019062 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019063 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019064 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019065
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019066 ENTER();
19067
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019068 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019069 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019070 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019072 return -EINVAL;
19073 }
19074
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019075 if (!pmksa) {
19076 hddLog(LOGE, FL("pmksa is NULL"));
19077 return -EINVAL;
19078 }
19079
19080 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019081 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019082 pmksa->bssid, pmksa->pmkid);
19083 return -EINVAL;
19084 }
19085
19086 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19087 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19088
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19090 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019091 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019092 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019093 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019094 }
19095
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019096 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019097 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19098
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019099 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19100 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019101
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019102 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019103 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019104 &pmk_id, 1, FALSE);
19105
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19107 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19108 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019109
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019110 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019111 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019112}
19113
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019114static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19115 struct cfg80211_pmksa *pmksa)
19116{
19117 int ret;
19118
19119 vos_ssr_protect(__func__);
19120 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19121 vos_ssr_unprotect(__func__);
19122
19123 return ret;
19124}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019125
Wilson Yang6507c4e2013-10-01 20:11:19 -070019126
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019127static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019128 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019129{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19131 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019132 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019133 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019135 ENTER();
19136
Wilson Yang6507c4e2013-10-01 20:11:19 -070019137 /* Validate pAdapter */
19138 if (NULL == pAdapter)
19139 {
19140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19141 return -EINVAL;
19142 }
19143
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019144 if (!pmksa) {
19145 hddLog(LOGE, FL("pmksa is NULL"));
19146 return -EINVAL;
19147 }
19148
19149 if (!pmksa->bssid) {
19150 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19151 return -EINVAL;
19152 }
19153
Kiet Lam98c46a12014-10-31 15:34:57 -070019154 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19155 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19156
Wilson Yang6507c4e2013-10-01 20:11:19 -070019157 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19158 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019159 if (0 != status)
19160 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019161 return status;
19162 }
19163
19164 /*Retrieve halHandle*/
19165 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19166
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19168 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19169 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019170 /* Delete the PMKID CSR cache */
19171 if (eHAL_STATUS_SUCCESS !=
19172 sme_RoamDelPMKIDfromCache(halHandle,
19173 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19174 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19175 MAC_ADDR_ARRAY(pmksa->bssid));
19176 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019177 }
19178
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019179 EXIT();
19180 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019181}
19182
Wilson Yang6507c4e2013-10-01 20:11:19 -070019183
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019184static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19185 struct cfg80211_pmksa *pmksa)
19186{
19187 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019188
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019189 vos_ssr_protect(__func__);
19190 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19191 vos_ssr_unprotect(__func__);
19192
19193 return ret;
19194
19195}
19196
19197static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019198{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19200 tHalHandle halHandle;
19201 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019202 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019203
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019204 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019205
19206 /* Validate pAdapter */
19207 if (NULL == pAdapter)
19208 {
19209 hddLog(VOS_TRACE_LEVEL_ERROR,
19210 "%s: Invalid Adapter" ,__func__);
19211 return -EINVAL;
19212 }
19213
19214 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19215 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019216 if (0 != status)
19217 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019218 return status;
19219 }
19220
19221 /*Retrieve halHandle*/
19222 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19223
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019224 /* Flush the PMKID cache in CSR */
19225 if (eHAL_STATUS_SUCCESS !=
19226 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19228 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019229 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019230 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019231 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019232}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019233
19234static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19235{
19236 int ret;
19237
19238 vos_ssr_protect(__func__);
19239 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19240 vos_ssr_unprotect(__func__);
19241
19242 return ret;
19243}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019244#endif
19245
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019246#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019247static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19248 struct net_device *dev,
19249 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019250{
19251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19252 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019253 hdd_context_t *pHddCtx;
19254 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019256 ENTER();
19257
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019258 if (NULL == pAdapter)
19259 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019261 return -ENODEV;
19262 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019263 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19264 ret = wlan_hdd_validate_context(pHddCtx);
19265 if (0 != ret)
19266 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019267 return ret;
19268 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019269 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019270 if (NULL == pHddStaCtx)
19271 {
19272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19273 return -EINVAL;
19274 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019275
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019276 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19277 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19278 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019279 // Added for debug on reception of Re-assoc Req.
19280 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19281 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019282 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019283 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019284 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019285 }
19286
19287#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019288 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019289 ftie->ie_len);
19290#endif
19291
19292 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019293 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19294 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019295 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019296
19297 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019298 return 0;
19299}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019300
19301static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19302 struct net_device *dev,
19303 struct cfg80211_update_ft_ies_params *ftie)
19304{
19305 int ret;
19306
19307 vos_ssr_protect(__func__);
19308 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19309 vos_ssr_unprotect(__func__);
19310
19311 return ret;
19312}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019313#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019314
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019315#ifdef FEATURE_WLAN_SCAN_PNO
19316
19317void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19318 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19319{
19320 int ret;
19321 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19322 hdd_context_t *pHddCtx;
19323
Nirav Shah80830bf2013-12-31 16:35:12 +053019324 ENTER();
19325
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019326 if (NULL == pAdapter)
19327 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019329 "%s: HDD adapter is Null", __func__);
19330 return ;
19331 }
19332
19333 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19334 if (NULL == pHddCtx)
19335 {
19336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19337 "%s: HDD context is Null!!!", __func__);
19338 return ;
19339 }
19340
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019341 spin_lock(&pHddCtx->schedScan_lock);
19342 if (TRUE == pHddCtx->isWiphySuspended)
19343 {
19344 pHddCtx->isSchedScanUpdatePending = TRUE;
19345 spin_unlock(&pHddCtx->schedScan_lock);
19346 hddLog(VOS_TRACE_LEVEL_INFO,
19347 "%s: Update cfg80211 scan database after it resume", __func__);
19348 return ;
19349 }
19350 spin_unlock(&pHddCtx->schedScan_lock);
19351
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019352 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19353
19354 if (0 > ret)
19355 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019356 else
19357 {
19358 /* Acquire wakelock to handle the case where APP's tries to suspend
19359 * immediatly after the driver gets connect request(i.e after pno)
19360 * from supplicant, this result in app's is suspending and not able
19361 * to process the connect request to AP */
19362 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19363 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019364 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19366 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019367}
19368
19369/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019370 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019371 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019372 */
19373static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19374{
19375 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19376 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019377 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019378 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19379 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019380
19381 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19382 {
19383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19384 "%s: PNO is allowed only in STA interface", __func__);
19385 return eHAL_STATUS_FAILURE;
19386 }
19387
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019388 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19389
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019390 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019391 * active sessions. PNO is allowed only in case when sap session
19392 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019393 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019394 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19395 {
19396 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019397 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019398
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019399 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19400 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19401 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19402 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019403 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19404 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019405 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019406 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019407 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019408 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019409 }
19410 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19411 pAdapterNode = pNext;
19412 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019413 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019414}
19415
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019416void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19417{
19418 hdd_adapter_t *pAdapter = callbackContext;
19419 hdd_context_t *pHddCtx;
19420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019421 ENTER();
19422
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019423 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19424 {
19425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19426 FL("Invalid adapter or adapter has invalid magic"));
19427 return;
19428 }
19429
19430 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19431 if (0 != wlan_hdd_validate_context(pHddCtx))
19432 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019433 return;
19434 }
19435
c_hpothub53c45d2014-08-18 16:53:14 +053019436 if (VOS_STATUS_SUCCESS != status)
19437 {
19438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019439 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019440 pHddCtx->isPnoEnable = FALSE;
19441 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019442
19443 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19444 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019445 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019446}
19447
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019448#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19449 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19450/**
19451 * hdd_config_sched_scan_plan() - configures the sched scan plans
19452 * from the framework.
19453 * @pno_req: pointer to PNO scan request
19454 * @request: pointer to scan request from framework
19455 *
19456 * Return: None
19457 */
19458static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19459 struct cfg80211_sched_scan_request *request,
19460 hdd_context_t *hdd_ctx)
19461{
19462 v_U32_t i = 0;
19463
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019464 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019465 for (i = 0; i < request->n_scan_plans; i++)
19466 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019467 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19468 request->scan_plans[i].iterations;
19469 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19470 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019471 }
19472}
19473#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019474static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019475 struct cfg80211_sched_scan_request *request,
19476 hdd_context_t *hdd_ctx)
19477{
19478 v_U32_t i, temp_int;
19479 /* Driver gets only one time interval which is hardcoded in
19480 * supplicant for 10000ms. Taking power consumption into account 6
19481 * timers will be used, Timervalue is increased exponentially
19482 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19483 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19484 * If it is set to 0 only one timer will be used and PNO scan cycle
19485 * will be repeated after each interval specified by supplicant
19486 * till PNO is disabled.
19487 */
19488 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019489 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019490 HDD_PNO_SCAN_TIMERS_SET_ONE;
19491 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019492 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019493 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19494
19495 temp_int = (request->interval)/1000;
19496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19497 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19498 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019499 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019500 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019501 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019502 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019503 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019504 temp_int *= 2;
19505 }
19506 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019507 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019508}
19509#endif
19510
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019511/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019512 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19513 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019514 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019515static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019516 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19517{
19518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019519 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019520 hdd_context_t *pHddCtx;
19521 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019522 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019523 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19524 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019525 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19526 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019527 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019528 hdd_config_t *pConfig = NULL;
19529 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019530
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019531 ENTER();
19532
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019533 if (NULL == pAdapter)
19534 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019536 "%s: HDD adapter is Null", __func__);
19537 return -ENODEV;
19538 }
19539
19540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019541 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019542
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019543 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019544 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019545 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019546 }
19547
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019548 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019549 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19550 if (NULL == hHal)
19551 {
19552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19553 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019554 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019555 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019556 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19557 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19558 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019559 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019560 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019561 {
19562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19563 "%s: aborting the existing scan is unsuccessfull", __func__);
19564 return -EBUSY;
19565 }
19566
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019567 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019568 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019570 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019571 return -EBUSY;
19572 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019573
c_hpothu37f21312014-04-09 21:49:54 +053019574 if (TRUE == pHddCtx->isPnoEnable)
19575 {
19576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19577 FL("already PNO is enabled"));
19578 return -EBUSY;
19579 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019580
19581 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19582 {
19583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19584 "%s: abort ROC failed ", __func__);
19585 return -EBUSY;
19586 }
19587
c_hpothu37f21312014-04-09 21:49:54 +053019588 pHddCtx->isPnoEnable = TRUE;
19589
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019590 pnoRequest.enable = 1; /*Enable PNO */
19591 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019592
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019593 if (( !pnoRequest.ucNetworksCount ) ||
19594 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019595 {
19596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019597 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019598 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019599 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019600 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019601 goto error;
19602 }
19603
19604 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19605 {
19606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019607 "%s: Incorrect number of channels %d",
19608 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019609 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019610 goto error;
19611 }
19612
19613 /* Framework provides one set of channels(all)
19614 * common for all saved profile */
19615 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19616 channels_allowed, &num_channels_allowed))
19617 {
19618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19619 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019620 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019621 goto error;
19622 }
19623 /* Checking each channel against allowed channel list */
19624 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019625 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019626 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019627 char chList [(request->n_channels*5)+1];
19628 int len;
19629 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019630 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019631 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019632 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019633 if (request->channels[i]->hw_value == channels_allowed[indx])
19634 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019635 if ((!pConfig->enableDFSPnoChnlScan) &&
19636 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19637 {
19638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19639 "%s : Dropping DFS channel : %d",
19640 __func__,channels_allowed[indx]);
19641 num_ignore_dfs_ch++;
19642 break;
19643 }
19644
Nirav Shah80830bf2013-12-31 16:35:12 +053019645 valid_ch[num_ch++] = request->channels[i]->hw_value;
19646 len += snprintf(chList+len, 5, "%d ",
19647 request->channels[i]->hw_value);
19648 break ;
19649 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019650 }
19651 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019652 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019653
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019654 /*If all channels are DFS and dropped, then ignore the PNO request*/
19655 if (num_ignore_dfs_ch == request->n_channels)
19656 {
19657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19658 "%s : All requested channels are DFS channels", __func__);
19659 ret = -EINVAL;
19660 goto error;
19661 }
19662 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019663
19664 pnoRequest.aNetworks =
19665 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19666 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019667 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019668 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19669 FL("failed to allocate memory aNetworks %u"),
19670 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19671 goto error;
19672 }
19673 vos_mem_zero(pnoRequest.aNetworks,
19674 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19675
19676 /* Filling per profile params */
19677 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19678 {
19679 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019680 request->match_sets[i].ssid.ssid_len;
19681
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019682 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19683 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019684 {
19685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019686 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019687 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019688 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019689 goto error;
19690 }
19691
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019692 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019693 request->match_sets[i].ssid.ssid,
19694 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19696 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019697 i, pnoRequest.aNetworks[i].ssId.ssId);
19698 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19699 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19700 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019701
19702 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019703 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19704 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019705
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019706 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019707 }
19708
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019709 for (i = 0; i < request->n_ssids; i++)
19710 {
19711 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019712 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019713 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019714 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019715 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019716 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019717 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019718 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019719 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019720 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019721 break;
19722 }
19723 j++;
19724 }
19725 }
19726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19727 "Number of hidden networks being Configured = %d",
19728 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019730 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019731
19732 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19733 if (pnoRequest.p24GProbeTemplate == NULL)
19734 {
19735 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19736 FL("failed to allocate memory p24GProbeTemplate %u"),
19737 SIR_PNO_MAX_PB_REQ_SIZE);
19738 goto error;
19739 }
19740
19741 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19742 if (pnoRequest.p5GProbeTemplate == NULL)
19743 {
19744 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19745 FL("failed to allocate memory p5GProbeTemplate %u"),
19746 SIR_PNO_MAX_PB_REQ_SIZE);
19747 goto error;
19748 }
19749
19750 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19751 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19752
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019753 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19754 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019755 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019756 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19757 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19758 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019759
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019760 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19761 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19762 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019763 }
19764
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019765 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019766
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019767 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019768
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019769 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019770 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19771 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019772 pAdapter->pno_req_status = 0;
19773
Nirav Shah80830bf2013-12-31 16:35:12 +053019774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19775 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019776 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19777 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019778
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019779 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019780 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019781 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19782 if (eHAL_STATUS_SUCCESS != status)
19783 {
19784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019785 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019786 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019787 goto error;
19788 }
19789
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019790 ret = wait_for_completion_timeout(
19791 &pAdapter->pno_comp_var,
19792 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19793 if (0 >= ret)
19794 {
19795 // Did not receive the response for PNO enable in time.
19796 // Assuming the PNO enable was success.
19797 // Returning error from here, because we timeout, results
19798 // in side effect of Wifi (Wifi Setting) not to work.
19799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19800 FL("Timed out waiting for PNO to be Enabled"));
19801 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019802 }
19803
19804 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019805 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019806
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019807error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19809 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019810 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019811 if (pnoRequest.aNetworks)
19812 vos_mem_free(pnoRequest.aNetworks);
19813 if (pnoRequest.p24GProbeTemplate)
19814 vos_mem_free(pnoRequest.p24GProbeTemplate);
19815 if (pnoRequest.p5GProbeTemplate)
19816 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019817
19818 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019819 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019820}
19821
19822/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019823 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19824 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019825 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019826static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19827 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19828{
19829 int ret;
19830
19831 vos_ssr_protect(__func__);
19832 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19833 vos_ssr_unprotect(__func__);
19834
19835 return ret;
19836}
19837
19838/*
19839 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19840 * Function to disable PNO
19841 */
19842static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019843 struct net_device *dev)
19844{
19845 eHalStatus status = eHAL_STATUS_FAILURE;
19846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19847 hdd_context_t *pHddCtx;
19848 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019849 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019850 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019851
19852 ENTER();
19853
19854 if (NULL == pAdapter)
19855 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019857 "%s: HDD adapter is Null", __func__);
19858 return -ENODEV;
19859 }
19860
19861 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019862
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019863 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019864 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019866 "%s: HDD context is Null", __func__);
19867 return -ENODEV;
19868 }
19869
19870 /* The return 0 is intentional when isLogpInProgress and
19871 * isLoadUnloadInProgress. We did observe a crash due to a return of
19872 * failure in sched_scan_stop , especially for a case where the unload
19873 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19874 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19875 * success. If it returns a failure , then its next invocation due to the
19876 * clean up of the second interface will have the dev pointer corresponding
19877 * to the first one leading to a crash.
19878 */
19879 if (pHddCtx->isLogpInProgress)
19880 {
19881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19882 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019883 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019884 return ret;
19885 }
19886
Mihir Shete18156292014-03-11 15:38:30 +053019887 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019888 {
19889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19890 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19891 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019892 }
19893
19894 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19895 if (NULL == hHal)
19896 {
19897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19898 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019899 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019900 }
19901
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019902 pnoRequest.enable = 0; /* Disable PNO */
19903 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019904
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19906 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19907 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019908
19909 INIT_COMPLETION(pAdapter->pno_comp_var);
19910 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19911 pnoRequest.callbackContext = pAdapter;
19912 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019913 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019914 pAdapter->sessionId,
19915 NULL, pAdapter);
19916 if (eHAL_STATUS_SUCCESS != status)
19917 {
19918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19919 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019920 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019921 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019922 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019923 ret = wait_for_completion_timeout(
19924 &pAdapter->pno_comp_var,
19925 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19926 if (0 >= ret)
19927 {
19928 // Did not receive the response for PNO disable in time.
19929 // Assuming the PNO disable was success.
19930 // Returning error from here, because we timeout, results
19931 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019933 FL("Timed out waiting for PNO to be disabled"));
19934 ret = 0;
19935 }
19936
19937 ret = pAdapter->pno_req_status;
19938 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019939
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019940error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019942 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019943
19944 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019945 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019946}
19947
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019948/*
19949 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19950 * NL interface to disable PNO
19951 */
19952static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19953 struct net_device *dev)
19954{
19955 int ret;
19956
19957 vos_ssr_protect(__func__);
19958 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19959 vos_ssr_unprotect(__func__);
19960
19961 return ret;
19962}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019963#endif /*FEATURE_WLAN_SCAN_PNO*/
19964
19965
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019966#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019967#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019968static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19969 struct net_device *dev,
19970 u8 *peer, u8 action_code,
19971 u8 dialog_token,
19972 u16 status_code, u32 peer_capability,
19973 const u8 *buf, size_t len)
19974#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19976 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019977static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19978 struct net_device *dev,
19979 const u8 *peer, u8 action_code,
19980 u8 dialog_token, u16 status_code,
19981 u32 peer_capability, bool initiator,
19982 const u8 *buf, size_t len)
19983#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19984static 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, const u8 *buf,
19989 size_t len)
19990#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19991static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19992 struct net_device *dev,
19993 u8 *peer, u8 action_code,
19994 u8 dialog_token,
19995 u16 status_code, u32 peer_capability,
19996 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019997#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019998static 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, const u8 *buf,
20003 size_t len)
20004#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020005#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020006{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020007 hdd_adapter_t *pAdapter;
20008 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020009 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020010 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020011 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020012 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020013 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020014 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020015#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020016 u32 peer_capability = 0;
20017#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020018 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020019 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020020 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020021
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020022 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20023 if (NULL == pAdapter)
20024 {
20025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20026 "%s: Adapter is NULL",__func__);
20027 return -EINVAL;
20028 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020029 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20030 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20031 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020032
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020033 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020034 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020035 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020037 "Invalid arguments");
20038 return -EINVAL;
20039 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020040
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020041 if (pHddCtx->isLogpInProgress)
20042 {
20043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20044 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020045 wlan_hdd_tdls_set_link_status(pAdapter,
20046 peer,
20047 eTDLS_LINK_IDLE,
20048 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020049 return -EBUSY;
20050 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020051
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020052 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20053 {
20054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20055 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20056 return -EAGAIN;
20057 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020058
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020059 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20060 if (!pHddTdlsCtx) {
20061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20062 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020063 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020064 }
20065
Hoonki Lee27511902013-03-14 18:19:06 -070020066 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020067 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020069 "%s: TDLS mode is disabled OR not enabled in FW."
20070 MAC_ADDRESS_STR " action %d declined.",
20071 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020072 return -ENOTSUPP;
20073 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020074
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020075 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20076
20077 if( NULL == pHddStaCtx )
20078 {
20079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20080 "%s: HDD station context NULL ",__func__);
20081 return -EINVAL;
20082 }
20083
20084 /* STA should be connected and authenticated
20085 * before sending any TDLS frames
20086 */
20087 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20088 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20089 {
20090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20091 "STA is not connected or unauthenticated. "
20092 "connState %u, uIsAuthenticated %u",
20093 pHddStaCtx->conn_info.connState,
20094 pHddStaCtx->conn_info.uIsAuthenticated);
20095 return -EAGAIN;
20096 }
20097
Hoonki Lee27511902013-03-14 18:19:06 -070020098 /* other than teardown frame, other mgmt frames are not sent if disabled */
20099 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20100 {
20101 /* if tdls_mode is disabled to respond to peer's request */
20102 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20103 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020105 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020106 " TDLS mode is disabled. action %d declined.",
20107 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020108
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020109 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020110 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020111
20112 if (vos_max_concurrent_connections_reached())
20113 {
20114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20115 return -EINVAL;
20116 }
Hoonki Lee27511902013-03-14 18:19:06 -070020117 }
20118
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020119 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20120 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020121 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020122 {
20123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020124 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020125 " TDLS setup is ongoing. action %d declined.",
20126 __func__, MAC_ADDR_ARRAY(peer), action_code);
20127 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020128 }
20129 }
20130
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020131 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20132 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020133 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020134 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20135 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020136 {
20137 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20138 we return error code at 'add_station()'. Hence we have this
20139 check again in addtion to add_station().
20140 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020141 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020142 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20144 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020145 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20146 __func__, MAC_ADDR_ARRAY(peer), action_code,
20147 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020148 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020149 }
20150 else
20151 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020152 /* maximum reached. tweak to send error code to peer and return
20153 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020154 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20156 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020157 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20158 __func__, MAC_ADDR_ARRAY(peer), status_code,
20159 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020160 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020161 /* fall through to send setup resp with failure status
20162 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020163 }
20164 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020165 else
20166 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020167 mutex_lock(&pHddCtx->tdls_lock);
20168 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020169 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020170 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020171 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020173 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20174 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020175 return -EPERM;
20176 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020177 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020178 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020179 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020180
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020182 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020183 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20184 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020185
Hoonki Leea34dd892013-02-05 22:56:02 -080020186 /*Except teardown responder will not be used so just make 0*/
20187 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020188 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020189 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020190
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020191 mutex_lock(&pHddCtx->tdls_lock);
20192 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020193
20194 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20195 responder = pTdlsPeer->is_responder;
20196 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020197 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020199 "%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 -070020200 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20201 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020202 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020203 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020204 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020205 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020206 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020207
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020208 /* Discard TDLS setup if peer is removed by user app */
20209 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20210 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20211 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20212 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20213
20214 mutex_lock(&pHddCtx->tdls_lock);
20215 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20216 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20217 mutex_unlock(&pHddCtx->tdls_lock);
20218 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20219 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20220 MAC_ADDR_ARRAY(peer), action_code);
20221 return -EINVAL;
20222 }
20223 mutex_unlock(&pHddCtx->tdls_lock);
20224 }
20225
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020226 /* For explicit trigger of DIS_REQ come out of BMPS for
20227 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020228 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020229 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020230 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20231 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020232 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020233 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020235 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20236 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020237 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20238 if (status != VOS_STATUS_SUCCESS) {
20239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020240 } else {
20241 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020242 }
Hoonki Lee14621352013-04-16 17:51:19 -070020243 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020244 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020245 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20247 }
20248 }
Hoonki Lee14621352013-04-16 17:51:19 -070020249 }
20250
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020251 /* make sure doesn't call send_mgmt() while it is pending */
20252 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20253 {
20254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020255 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020256 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020257 ret = -EBUSY;
20258 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020259 }
20260
20261 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020262 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20263
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020264 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20265 pAdapter->sessionId, peer, action_code, dialog_token,
20266 status_code, peer_capability, (tANI_U8 *)buf, len,
20267 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020268
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020269 if (VOS_STATUS_SUCCESS != status)
20270 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20272 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020273 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020274 ret = -EINVAL;
20275 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020276 }
20277
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20279 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20280 WAIT_TIME_TDLS_MGMT);
20281
Hoonki Leed37cbb32013-04-20 00:31:14 -070020282 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20283 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20284
20285 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020286 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020288 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020289 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020290 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020291
20292 if (pHddCtx->isLogpInProgress)
20293 {
20294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20295 "%s: LOGP in Progress. Ignore!!!", __func__);
20296 return -EAGAIN;
20297 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020298 if (rc <= 0)
20299 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20300 WLAN_LOG_INDICATOR_HOST_DRIVER,
20301 WLAN_LOG_REASON_HDD_TIME_OUT,
20302 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020303
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020304 ret = -EINVAL;
20305 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020306 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020307 else
20308 {
20309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20310 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20311 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20312 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020313
Gopichand Nakkala05922802013-03-14 12:23:19 -070020314 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020315 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020316 ret = max_sta_failed;
20317 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020318 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020319
Hoonki Leea34dd892013-02-05 22:56:02 -080020320 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20321 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020322 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20324 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020325 }
20326 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20327 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020328 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20330 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020331 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020332
20333 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020334
20335tx_failed:
20336 /* add_station will be called before sending TDLS_SETUP_REQ and
20337 * TDLS_SETUP_RSP and as part of add_station driver will enable
20338 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20339 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20340 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20341 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20342 */
20343
20344 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20345 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20346 wlan_hdd_tdls_check_bmps(pAdapter);
20347 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020348}
20349
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020350#if TDLS_MGMT_VERSION2
20351static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20352 u8 *peer, u8 action_code, u8 dialog_token,
20353 u16 status_code, u32 peer_capability,
20354 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020355#else /* TDLS_MGMT_VERSION2 */
20356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20357static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20358 struct net_device *dev,
20359 const u8 *peer, u8 action_code,
20360 u8 dialog_token, u16 status_code,
20361 u32 peer_capability, bool initiator,
20362 const u8 *buf, size_t len)
20363#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,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, const u8 *buf,
20369 size_t len)
20370#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20371static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20372 struct net_device *dev,
20373 u8 *peer, u8 action_code,
20374 u8 dialog_token,
20375 u16 status_code, u32 peer_capability,
20376 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020377#else
20378static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20379 u8 *peer, u8 action_code, u8 dialog_token,
20380 u16 status_code, const u8 *buf, size_t len)
20381#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020382#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020383{
20384 int ret;
20385
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020386 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020387#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020388 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20389 dialog_token, status_code,
20390 peer_capability, buf, len);
20391#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020392#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20393 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020394 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20395 dialog_token, status_code,
20396 peer_capability, initiator,
20397 buf, len);
20398#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20399 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20400 dialog_token, status_code,
20401 peer_capability, buf, len);
20402#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20403 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20404 dialog_token, status_code,
20405 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020406#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020407 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20408 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020409#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020410#endif
20411 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020412
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020413 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020414}
Atul Mittal115287b2014-07-08 13:26:33 +053020415
20416int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020417#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20418 const u8 *peer,
20419#else
Atul Mittal115287b2014-07-08 13:26:33 +053020420 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020421#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020422 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020423 cfg80211_exttdls_callback callback)
20424{
20425
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020426 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020427 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020428 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20430 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20431 __func__, MAC_ADDR_ARRAY(peer));
20432
20433 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20434 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20435
20436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020437 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20438 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20439 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020440 return -ENOTSUPP;
20441 }
20442
20443 /* To cater the requirement of establishing the TDLS link
20444 * irrespective of the data traffic , get an entry of TDLS peer.
20445 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020446 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020447 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20448 if (pTdlsPeer == NULL) {
20449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20450 "%s: peer " MAC_ADDRESS_STR " not existing",
20451 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020452 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020453 return -EINVAL;
20454 }
20455
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020456 /* check FW TDLS Off Channel capability */
20457 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020458 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020459 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020460 {
20461 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20462 pTdlsPeer->peerParams.global_operating_class =
20463 tdls_peer_params->global_operating_class;
20464 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20465 pTdlsPeer->peerParams.min_bandwidth_kbps =
20466 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020467 /* check configured channel is valid, non dfs and
20468 * not current operating channel */
20469 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20470 tdls_peer_params->channel)) &&
20471 (pHddStaCtx) &&
20472 (tdls_peer_params->channel !=
20473 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020474 {
20475 pTdlsPeer->isOffChannelConfigured = TRUE;
20476 }
20477 else
20478 {
20479 pTdlsPeer->isOffChannelConfigured = FALSE;
20480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20481 "%s: Configured Tdls Off Channel is not valid", __func__);
20482
20483 }
20484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020485 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20486 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020487 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020488 pTdlsPeer->isOffChannelConfigured,
20489 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020490 }
20491 else
20492 {
20493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020494 "%s: TDLS off channel FW capability %d, "
20495 "host capab %d or Invalid TDLS Peer Params", __func__,
20496 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20497 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020498 }
20499
Atul Mittal115287b2014-07-08 13:26:33 +053020500 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20501
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020502 mutex_unlock(&pHddCtx->tdls_lock);
20503
Atul Mittal115287b2014-07-08 13:26:33 +053020504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20505 " %s TDLS Add Force Peer Failed",
20506 __func__);
20507 return -EINVAL;
20508 }
20509 /*EXT TDLS*/
20510
20511 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020512 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20514 " %s TDLS set callback Failed",
20515 __func__);
20516 return -EINVAL;
20517 }
20518
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020519 mutex_unlock(&pHddCtx->tdls_lock);
20520
Atul Mittal115287b2014-07-08 13:26:33 +053020521 return(0);
20522
20523}
20524
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020525int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20526#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20527 const u8 *peer
20528#else
20529 u8 *peer
20530#endif
20531)
Atul Mittal115287b2014-07-08 13:26:33 +053020532{
20533
20534 hddTdlsPeer_t *pTdlsPeer;
20535 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020536
Atul Mittal115287b2014-07-08 13:26:33 +053020537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20538 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20539 __func__, MAC_ADDR_ARRAY(peer));
20540
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020541 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20543 return -EINVAL;
20544 }
20545
Atul Mittal115287b2014-07-08 13:26:33 +053020546 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20547 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20548
20549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020550 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20551 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20552 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020553 return -ENOTSUPP;
20554 }
20555
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020556 mutex_lock(&pHddCtx->tdls_lock);
20557 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020558
20559 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020560 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020561 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020562 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020563 __func__, MAC_ADDR_ARRAY(peer));
20564 return -EINVAL;
20565 }
20566 else {
20567 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20568 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020569 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20570 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020571 /* if channel switch is configured, reset
20572 the channel for this peer */
20573 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20574 {
20575 pTdlsPeer->peerParams.channel = 0;
20576 pTdlsPeer->isOffChannelConfigured = FALSE;
20577 }
Atul Mittal115287b2014-07-08 13:26:33 +053020578 }
20579
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020580 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020581 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020583 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020584 }
Atul Mittal115287b2014-07-08 13:26:33 +053020585
20586 /*EXT TDLS*/
20587
20588 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020589 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20591 " %s TDLS set callback Failed",
20592 __func__);
20593 return -EINVAL;
20594 }
Atul Mittal115287b2014-07-08 13:26:33 +053020595
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020596 mutex_unlock(&pHddCtx->tdls_lock);
20597
20598 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020599}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020600static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020601#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20602 const u8 *peer,
20603#else
20604 u8 *peer,
20605#endif
20606 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020607{
20608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20609 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020610 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020611 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020613 ENTER();
20614
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020615 if (!pAdapter) {
20616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20617 return -EINVAL;
20618 }
20619
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20621 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20622 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020623 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020624 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020626 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020627 return -EINVAL;
20628 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020629
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020630 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020631 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020632 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020633 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020634 }
20635
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020636
20637 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020638 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020639 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020641 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20642 "Cannot process TDLS commands",
20643 pHddCtx->cfg_ini->fEnableTDLSSupport,
20644 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020645 return -ENOTSUPP;
20646 }
20647
20648 switch (oper) {
20649 case NL80211_TDLS_ENABLE_LINK:
20650 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020651 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020652 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020653 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20654 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020655 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020656 tANI_U16 numCurrTdlsPeers = 0;
20657 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020658 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020659 tSirMacAddr peerMac;
20660 int channel;
20661 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020662
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20664 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20665 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020666
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020667 mutex_lock(&pHddCtx->tdls_lock);
20668 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020669 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020670 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020671 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20673 " (oper %d) not exsting. ignored",
20674 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20675 return -EINVAL;
20676 }
20677
20678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20679 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20680 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20681 "NL80211_TDLS_ENABLE_LINK");
20682
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020683 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20684 {
20685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20686 MAC_ADDRESS_STR " failed",
20687 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020688 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020689 return -EINVAL;
20690 }
20691
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020692 /* before starting tdls connection, set tdls
20693 * off channel established status to default value */
20694 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020695
20696 mutex_unlock(&pHddCtx->tdls_lock);
20697
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020698 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020699 /* TDLS Off Channel, Disable tdls channel switch,
20700 when there are more than one tdls link */
20701 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020702 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020703 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020704 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020705 /* get connected peer and send disable tdls off chan */
20706 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020707 if ((connPeer) &&
20708 (connPeer->isOffChannelSupported == TRUE) &&
20709 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020710 {
20711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20712 "%s: More then one peer connected, Disable "
20713 "TDLS channel switch", __func__);
20714
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020715 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020716 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20717 channel = connPeer->peerParams.channel;
20718
20719 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020720
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020721 ret = sme_SendTdlsChanSwitchReq(
20722 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020723 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020724 peerMac,
20725 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020726 TDLS_OFF_CHANNEL_BW_OFFSET,
20727 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020728 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020729 hddLog(VOS_TRACE_LEVEL_ERROR,
20730 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020731 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020732 }
20733 else
20734 {
20735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20736 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020737 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020738 "isOffChannelConfigured %d",
20739 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020740 (connPeer ? (connPeer->isOffChannelSupported)
20741 : -1),
20742 (connPeer ? (connPeer->isOffChannelConfigured)
20743 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020744 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020745 }
20746 }
20747
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020748 mutex_lock(&pHddCtx->tdls_lock);
20749 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20750 if ( NULL == pTdlsPeer ) {
20751 mutex_unlock(&pHddCtx->tdls_lock);
20752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20753 "%s: " MAC_ADDRESS_STR
20754 " (oper %d) peer got freed in other context. ignored",
20755 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20756 return -EINVAL;
20757 }
20758 peer_status = pTdlsPeer->link_status;
20759 mutex_unlock(&pHddCtx->tdls_lock);
20760
20761 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020762 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020763 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020764
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020765 if (0 != wlan_hdd_tdls_get_link_establish_params(
20766 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020768 return -EINVAL;
20769 }
20770 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020771
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020772 ret = sme_SendTdlsLinkEstablishParams(
20773 WLAN_HDD_GET_HAL_CTX(pAdapter),
20774 pAdapter->sessionId, peer,
20775 &tdlsLinkEstablishParams);
20776 if (ret != VOS_STATUS_SUCCESS) {
20777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20778 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020779 /* Send TDLS peer UAPSD capabilities to the firmware and
20780 * register with the TL on after the response for this operation
20781 * is received .
20782 */
20783 ret = wait_for_completion_interruptible_timeout(
20784 &pAdapter->tdls_link_establish_req_comp,
20785 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020786
20787 mutex_lock(&pHddCtx->tdls_lock);
20788 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20789 if ( NULL == pTdlsPeer ) {
20790 mutex_unlock(&pHddCtx->tdls_lock);
20791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20792 "%s %d: " MAC_ADDRESS_STR
20793 " (oper %d) peer got freed in other context. ignored",
20794 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20795 (int)oper);
20796 return -EINVAL;
20797 }
20798 peer_status = pTdlsPeer->link_status;
20799 mutex_unlock(&pHddCtx->tdls_lock);
20800
20801 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020802 {
20803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020804 FL("Link Establish Request Failed Status %ld"),
20805 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020806 return -EINVAL;
20807 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020808 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020809
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020810 mutex_lock(&pHddCtx->tdls_lock);
20811 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20812 if ( NULL == pTdlsPeer ) {
20813 mutex_unlock(&pHddCtx->tdls_lock);
20814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20815 "%s: " MAC_ADDRESS_STR
20816 " (oper %d) peer got freed in other context. ignored",
20817 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20818 return -EINVAL;
20819 }
20820
Atul Mittal115287b2014-07-08 13:26:33 +053020821 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20822 eTDLS_LINK_CONNECTED,
20823 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020824 staDesc.ucSTAId = pTdlsPeer->staId;
20825 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020826
20827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20828 "%s: tdlsLinkEstablishParams of peer "
20829 MAC_ADDRESS_STR "uapsdQueues: %d"
20830 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20831 "isResponder: %d peerstaId: %d",
20832 __func__,
20833 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20834 tdlsLinkEstablishParams.uapsdQueues,
20835 tdlsLinkEstablishParams.qos,
20836 tdlsLinkEstablishParams.maxSp,
20837 tdlsLinkEstablishParams.isBufSta,
20838 tdlsLinkEstablishParams.isOffChannelSupported,
20839 tdlsLinkEstablishParams.isResponder,
20840 pTdlsPeer->staId);
20841
20842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20843 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20844 __func__,
20845 staDesc.ucSTAId,
20846 staDesc.ucQosEnabled);
20847
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020848 ret = WLANTL_UpdateTdlsSTAClient(
20849 pHddCtx->pvosContext,
20850 &staDesc);
20851 if (ret != VOS_STATUS_SUCCESS) {
20852 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20853 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020854
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020855 /* Mark TDLS client Authenticated .*/
20856 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20857 pTdlsPeer->staId,
20858 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020859 if (VOS_STATUS_SUCCESS == status)
20860 {
Hoonki Lee14621352013-04-16 17:51:19 -070020861 if (pTdlsPeer->is_responder == 0)
20862 {
20863 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020864 tdlsConnInfo_t *tdlsInfo;
20865
20866 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20867
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020868 if (!vos_timer_is_initialized(
20869 &pTdlsPeer->initiatorWaitTimeoutTimer))
20870 {
20871 /* Initialize initiator wait callback */
20872 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020873 &pTdlsPeer->initiatorWaitTimeoutTimer,
20874 VOS_TIMER_TYPE_SW,
20875 wlan_hdd_tdls_initiator_wait_cb,
20876 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020877 }
Hoonki Lee14621352013-04-16 17:51:19 -070020878 wlan_hdd_tdls_timer_restart(pAdapter,
20879 &pTdlsPeer->initiatorWaitTimeoutTimer,
20880 WAIT_TIME_TDLS_INITIATOR);
20881 /* suspend initiator TX until it receives direct packet from the
20882 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020883 ret = WLANTL_SuspendDataTx(
20884 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20885 &staId, NULL);
20886 if (ret != VOS_STATUS_SUCCESS) {
20887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20888 }
Hoonki Lee14621352013-04-16 17:51:19 -070020889 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020890
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020891 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020892 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020893 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020894 suppChannelLen =
20895 tdlsLinkEstablishParams.supportedChannelsLen;
20896
20897 if ((suppChannelLen > 0) &&
20898 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20899 {
20900 tANI_U8 suppPeerChannel = 0;
20901 int i = 0;
20902 for (i = 0U; i < suppChannelLen; i++)
20903 {
20904 suppPeerChannel =
20905 tdlsLinkEstablishParams.supportedChannels[i];
20906
20907 pTdlsPeer->isOffChannelSupported = FALSE;
20908 if (suppPeerChannel ==
20909 pTdlsPeer->peerParams.channel)
20910 {
20911 pTdlsPeer->isOffChannelSupported = TRUE;
20912 break;
20913 }
20914 }
20915 }
20916 else
20917 {
20918 pTdlsPeer->isOffChannelSupported = FALSE;
20919 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020920 }
20921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20922 "%s: TDLS channel switch request for channel "
20923 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020924 "%d isOffChannelSupported %d", __func__,
20925 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020926 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020927 suppChannelLen,
20928 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020929
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020930 /* TDLS Off Channel, Enable tdls channel switch,
20931 when their is only one tdls link and it supports */
20932 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20933 if ((numCurrTdlsPeers == 1) &&
20934 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20935 (TRUE == pTdlsPeer->isOffChannelConfigured))
20936 {
20937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20938 "%s: Send TDLS channel switch request for channel %d",
20939 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020940
20941 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020942 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20943 channel = pTdlsPeer->peerParams.channel;
20944
20945 mutex_unlock(&pHddCtx->tdls_lock);
20946
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020947 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20948 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020949 peerMac,
20950 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020951 TDLS_OFF_CHANNEL_BW_OFFSET,
20952 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020953 if (ret != VOS_STATUS_SUCCESS) {
20954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20955 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020956 }
20957 else
20958 {
20959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20960 "%s: TDLS channel switch request not sent"
20961 " numCurrTdlsPeers %d "
20962 "isOffChannelSupported %d "
20963 "isOffChannelConfigured %d",
20964 __func__, numCurrTdlsPeers,
20965 pTdlsPeer->isOffChannelSupported,
20966 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020967 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020968 }
20969
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020970 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020971 else
20972 mutex_unlock(&pHddCtx->tdls_lock);
20973
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020974 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020975
20976 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020977 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20978 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020979 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020980 int ac;
20981 uint8 ucAc[4] = { WLANTL_AC_VO,
20982 WLANTL_AC_VI,
20983 WLANTL_AC_BK,
20984 WLANTL_AC_BE };
20985 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20986 for(ac=0; ac < 4; ac++)
20987 {
20988 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20989 pTdlsPeer->staId, ucAc[ac],
20990 tlTid[ac], tlTid[ac], 0, 0,
20991 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020992 if (status != VOS_STATUS_SUCCESS) {
20993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20994 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020995 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020996 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020997 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020998
Bhargav Shah66896792015-10-01 18:17:37 +053020999 /* stop TCP delack timer if TDLS is enable */
21000 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21001 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021002 hdd_wlan_tdls_enable_link_event(peer,
21003 pTdlsPeer->isOffChannelSupported,
21004 pTdlsPeer->isOffChannelConfigured,
21005 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021006 }
21007 break;
21008 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021009 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021010 tANI_U16 numCurrTdlsPeers = 0;
21011 hddTdlsPeer_t *connPeer = NULL;
21012
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21014 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21015 __func__, MAC_ADDR_ARRAY(peer));
21016
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021017 mutex_lock(&pHddCtx->tdls_lock);
21018 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021019
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021020
Sunil Dutt41de4e22013-11-14 18:09:02 +053021021 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021022 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21024 " (oper %d) not exsting. ignored",
21025 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21026 return -EINVAL;
21027 }
21028
21029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21030 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21031 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21032 "NL80211_TDLS_DISABLE_LINK");
21033
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021034 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021035 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021036 long status;
21037
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021038 /* set tdls off channel status to false for this peer */
21039 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021040 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21041 eTDLS_LINK_TEARING,
21042 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21043 eTDLS_LINK_UNSPECIFIED:
21044 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021045 mutex_unlock(&pHddCtx->tdls_lock);
21046
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021047 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21048
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021049 status = sme_DeleteTdlsPeerSta(
21050 WLAN_HDD_GET_HAL_CTX(pAdapter),
21051 pAdapter->sessionId, peer );
21052 if (status != VOS_STATUS_SUCCESS) {
21053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21054 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021055
21056 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21057 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021058
21059 mutex_lock(&pHddCtx->tdls_lock);
21060 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21061 if ( NULL == pTdlsPeer ) {
21062 mutex_unlock(&pHddCtx->tdls_lock);
21063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21064 " peer was freed in other context",
21065 __func__, MAC_ADDR_ARRAY(peer));
21066 return -EINVAL;
21067 }
21068
Atul Mittal271a7652014-09-12 13:18:22 +053021069 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021070 eTDLS_LINK_IDLE,
21071 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021072 mutex_unlock(&pHddCtx->tdls_lock);
21073
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021074 if (status <= 0)
21075 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21077 "%s: Del station failed status %ld",
21078 __func__, status);
21079 return -EPERM;
21080 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021081
21082 /* TDLS Off Channel, Enable tdls channel switch,
21083 when their is only one tdls link and it supports */
21084 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21085 if (numCurrTdlsPeers == 1)
21086 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021087 tSirMacAddr peerMac;
21088 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021089
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021090 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021091 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021092
21093 if (connPeer == NULL) {
21094 mutex_unlock(&pHddCtx->tdls_lock);
21095 hddLog(VOS_TRACE_LEVEL_ERROR,
21096 "%s connPeer is NULL", __func__);
21097 return -EINVAL;
21098 }
21099
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021100 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21101 channel = connPeer->peerParams.channel;
21102
21103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21104 "%s: TDLS channel switch "
21105 "isOffChannelSupported %d "
21106 "isOffChannelConfigured %d "
21107 "isOffChannelEstablished %d",
21108 __func__,
21109 (connPeer ? connPeer->isOffChannelSupported : -1),
21110 (connPeer ? connPeer->isOffChannelConfigured : -1),
21111 (connPeer ? connPeer->isOffChannelEstablished : -1));
21112
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021113 if ((connPeer) &&
21114 (connPeer->isOffChannelSupported == TRUE) &&
21115 (connPeer->isOffChannelConfigured == TRUE))
21116 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021117 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021118 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021119 status = sme_SendTdlsChanSwitchReq(
21120 WLAN_HDD_GET_HAL_CTX(pAdapter),
21121 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021122 peerMac,
21123 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021124 TDLS_OFF_CHANNEL_BW_OFFSET,
21125 TDLS_CHANNEL_SWITCH_ENABLE);
21126 if (status != VOS_STATUS_SUCCESS) {
21127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21128 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021129 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021130 else
21131 mutex_unlock(&pHddCtx->tdls_lock);
21132 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021133 else
21134 {
21135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21136 "%s: TDLS channel switch request not sent "
21137 "numCurrTdlsPeers %d ",
21138 __func__, numCurrTdlsPeers);
21139 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021140 }
21141 else
21142 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021143 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21145 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021146 }
Bhargav Shah66896792015-10-01 18:17:37 +053021147 if (numCurrTdlsPeers == 0) {
21148 /* start TCP delack timer if TDLS is disable */
21149 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21150 hdd_manage_delack_timer(pHddCtx);
21151 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021152 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021153 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021154 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021155 {
Atul Mittal115287b2014-07-08 13:26:33 +053021156 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021157
Atul Mittal115287b2014-07-08 13:26:33 +053021158 if (0 != status)
21159 {
21160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021161 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021162 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021163 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021164 break;
21165 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021166 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021167 {
Atul Mittal115287b2014-07-08 13:26:33 +053021168 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21169 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021170 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021171 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021172
Atul Mittal115287b2014-07-08 13:26:33 +053021173 if (0 != status)
21174 {
21175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021176 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021177 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021178 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021179 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021180 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021181 case NL80211_TDLS_DISCOVERY_REQ:
21182 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021184 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021185 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021186 return -ENOTSUPP;
21187 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21189 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021190 return -ENOTSUPP;
21191 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021192
21193 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021194 return 0;
21195}
Chilam NG571c65a2013-01-19 12:27:36 +053021196
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021197static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21199 const u8 *peer,
21200#else
21201 u8 *peer,
21202#endif
21203 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021204{
21205 int ret;
21206
21207 vos_ssr_protect(__func__);
21208 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21209 vos_ssr_unprotect(__func__);
21210
21211 return ret;
21212}
21213
Chilam NG571c65a2013-01-19 12:27:36 +053021214int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21215 struct net_device *dev, u8 *peer)
21216{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021217 hddLog(VOS_TRACE_LEVEL_INFO,
21218 "tdls send discover req: "MAC_ADDRESS_STR,
21219 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021220#if TDLS_MGMT_VERSION2
21221 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21222 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21223#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21225 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21226 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21227#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21228 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21229 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21230#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21231 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21232 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21233#else
Chilam NG571c65a2013-01-19 12:27:36 +053021234 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21235 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021236#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021237#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021238}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021239#endif
21240
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021241#ifdef WLAN_FEATURE_GTK_OFFLOAD
21242/*
21243 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21244 * Callback rountine called upon receiving response for
21245 * get offload info
21246 */
21247void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21248 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21249{
21250
21251 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021252 tANI_U8 tempReplayCounter[8];
21253 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021254
21255 ENTER();
21256
21257 if (NULL == pAdapter)
21258 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021260 "%s: HDD adapter is Null", __func__);
21261 return ;
21262 }
21263
21264 if (NULL == pGtkOffloadGetInfoRsp)
21265 {
21266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21267 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21268 return ;
21269 }
21270
21271 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21272 {
21273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21274 "%s: wlan Failed to get replay counter value",
21275 __func__);
21276 return ;
21277 }
21278
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021279 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21280 /* Update replay counter */
21281 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21282 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21283
21284 {
21285 /* changing from little to big endian since supplicant
21286 * works on big endian format
21287 */
21288 int i;
21289 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21290
21291 for (i = 0; i < 8; i++)
21292 {
21293 tempReplayCounter[7-i] = (tANI_U8)p[i];
21294 }
21295 }
21296
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021297 /* Update replay counter to NL */
21298 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021299 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021300}
21301
21302/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021303 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021304 * This function is used to offload GTK rekeying job to the firmware.
21305 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021306int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021307 struct cfg80211_gtk_rekey_data *data)
21308{
21309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21310 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21311 hdd_station_ctx_t *pHddStaCtx;
21312 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021313 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021314 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021315 eHalStatus status = eHAL_STATUS_FAILURE;
21316
21317 ENTER();
21318
21319 if (NULL == pAdapter)
21320 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021322 "%s: HDD adapter is Null", __func__);
21323 return -ENODEV;
21324 }
21325
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021326 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21327 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21328 pAdapter->sessionId, pAdapter->device_mode));
21329
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021330 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021331 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021332 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021333 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021334 }
21335
21336 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21337 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21338 if (NULL == hHal)
21339 {
21340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21341 "%s: HAL context is Null!!!", __func__);
21342 return -EAGAIN;
21343 }
21344
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021345 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21346 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21347 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21348 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021349 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021350 {
21351 /* changing from big to little endian since driver
21352 * works on little endian format
21353 */
21354 tANI_U8 *p =
21355 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21356 int i;
21357
21358 for (i = 0; i < 8; i++)
21359 {
21360 p[7-i] = data->replay_ctr[i];
21361 }
21362 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021363
21364 if (TRUE == pHddCtx->hdd_wlan_suspended)
21365 {
21366 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021367 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21368 sizeof (tSirGtkOffloadParams));
21369 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021370 pAdapter->sessionId);
21371
21372 if (eHAL_STATUS_SUCCESS != status)
21373 {
21374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21375 "%s: sme_SetGTKOffload failed, returned %d",
21376 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021377
21378 /* Need to clear any trace of key value in the memory.
21379 * Thus zero out the memory even though it is local
21380 * variable.
21381 */
21382 vos_mem_zero(&hddGtkOffloadReqParams,
21383 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021384 return status;
21385 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21387 "%s: sme_SetGTKOffload successfull", __func__);
21388 }
21389 else
21390 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21392 "%s: wlan not suspended GTKOffload request is stored",
21393 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021394 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021395
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021396 /* Need to clear any trace of key value in the memory.
21397 * Thus zero out the memory even though it is local
21398 * variable.
21399 */
21400 vos_mem_zero(&hddGtkOffloadReqParams,
21401 sizeof(hddGtkOffloadReqParams));
21402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021403 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021404 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021405}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021406
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021407int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21408 struct cfg80211_gtk_rekey_data *data)
21409{
21410 int ret;
21411
21412 vos_ssr_protect(__func__);
21413 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21414 vos_ssr_unprotect(__func__);
21415
21416 return ret;
21417}
21418#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021419/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021420 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021421 * This function is used to set access control policy
21422 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021423static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21424 struct net_device *dev,
21425 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021426{
21427 int i;
21428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21429 hdd_hostapd_state_t *pHostapdState;
21430 tsap_Config_t *pConfig;
21431 v_CONTEXT_t pVosContext = NULL;
21432 hdd_context_t *pHddCtx;
21433 int status;
21434
21435 ENTER();
21436
21437 if (NULL == pAdapter)
21438 {
21439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21440 "%s: HDD adapter is Null", __func__);
21441 return -ENODEV;
21442 }
21443
21444 if (NULL == params)
21445 {
21446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21447 "%s: params is Null", __func__);
21448 return -EINVAL;
21449 }
21450
21451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21452 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021453 if (0 != status)
21454 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021455 return status;
21456 }
21457
21458 pVosContext = pHddCtx->pvosContext;
21459 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21460
21461 if (NULL == pHostapdState)
21462 {
21463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21464 "%s: pHostapdState is Null", __func__);
21465 return -EINVAL;
21466 }
21467
21468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21469 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021470 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21471 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21472 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021473
21474 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21475 {
21476 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21477
21478 /* default value */
21479 pConfig->num_accept_mac = 0;
21480 pConfig->num_deny_mac = 0;
21481
21482 /**
21483 * access control policy
21484 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21485 * listed in hostapd.deny file.
21486 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21487 * listed in hostapd.accept file.
21488 */
21489 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21490 {
21491 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21492 }
21493 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21494 {
21495 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21496 }
21497 else
21498 {
21499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21500 "%s:Acl Policy : %d is not supported",
21501 __func__, params->acl_policy);
21502 return -ENOTSUPP;
21503 }
21504
21505 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21506 {
21507 pConfig->num_accept_mac = params->n_acl_entries;
21508 for (i = 0; i < params->n_acl_entries; i++)
21509 {
21510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21511 "** Add ACL MAC entry %i in WhiletList :"
21512 MAC_ADDRESS_STR, i,
21513 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21514
21515 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21516 sizeof(qcmacaddr));
21517 }
21518 }
21519 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21520 {
21521 pConfig->num_deny_mac = params->n_acl_entries;
21522 for (i = 0; i < params->n_acl_entries; i++)
21523 {
21524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21525 "** Add ACL MAC entry %i in BlackList :"
21526 MAC_ADDRESS_STR, i,
21527 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21528
21529 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21530 sizeof(qcmacaddr));
21531 }
21532 }
21533
21534 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21535 {
21536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21537 "%s: SAP Set Mac Acl fail", __func__);
21538 return -EINVAL;
21539 }
21540 }
21541 else
21542 {
21543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021544 "%s: Invalid device_mode = %s (%d)",
21545 __func__, hdd_device_modetoString(pAdapter->device_mode),
21546 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021547 return -EINVAL;
21548 }
21549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021550 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021551 return 0;
21552}
21553
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021554static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21555 struct net_device *dev,
21556 const struct cfg80211_acl_data *params)
21557{
21558 int ret;
21559 vos_ssr_protect(__func__);
21560 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21561 vos_ssr_unprotect(__func__);
21562
21563 return ret;
21564}
21565
Leo Chang9056f462013-08-01 19:21:11 -070021566#ifdef WLAN_NL80211_TESTMODE
21567#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021568void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021569(
21570 void *pAdapter,
21571 void *indCont
21572)
21573{
Leo Changd9df8aa2013-09-26 13:32:26 -070021574 tSirLPHBInd *lphbInd;
21575 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021576 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021577
21578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021579 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021580
c_hpothu73f35e62014-04-18 13:40:08 +053021581 if (pAdapter == NULL)
21582 {
21583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21584 "%s: pAdapter is NULL\n",__func__);
21585 return;
21586 }
21587
Leo Chang9056f462013-08-01 19:21:11 -070021588 if (NULL == indCont)
21589 {
21590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021591 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021592 return;
21593 }
21594
c_hpothu73f35e62014-04-18 13:40:08 +053021595 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021596 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021597 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021598 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021599 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021600 GFP_ATOMIC);
21601 if (!skb)
21602 {
21603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21604 "LPHB timeout, NL buffer alloc fail");
21605 return;
21606 }
21607
Leo Changac3ba772013-10-07 09:47:04 -070021608 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021609 {
21610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21611 "WLAN_HDD_TM_ATTR_CMD put fail");
21612 goto nla_put_failure;
21613 }
Leo Changac3ba772013-10-07 09:47:04 -070021614 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021615 {
21616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21617 "WLAN_HDD_TM_ATTR_TYPE put fail");
21618 goto nla_put_failure;
21619 }
Leo Changac3ba772013-10-07 09:47:04 -070021620 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021621 sizeof(tSirLPHBInd), lphbInd))
21622 {
21623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21624 "WLAN_HDD_TM_ATTR_DATA put fail");
21625 goto nla_put_failure;
21626 }
Leo Chang9056f462013-08-01 19:21:11 -070021627 cfg80211_testmode_event(skb, GFP_ATOMIC);
21628 return;
21629
21630nla_put_failure:
21631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21632 "NLA Put fail");
21633 kfree_skb(skb);
21634
21635 return;
21636}
21637#endif /* FEATURE_WLAN_LPHB */
21638
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021639static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021640{
21641 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21642 int err = 0;
21643#ifdef FEATURE_WLAN_LPHB
21644 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021645 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021646
21647 ENTER();
21648
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021649 err = wlan_hdd_validate_context(pHddCtx);
21650 if (0 != err)
21651 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021652 return err;
21653 }
Leo Chang9056f462013-08-01 19:21:11 -070021654#endif /* FEATURE_WLAN_LPHB */
21655
21656 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21657 if (err)
21658 {
21659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21660 "%s Testmode INV ATTR", __func__);
21661 return err;
21662 }
21663
21664 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21665 {
21666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21667 "%s Testmode INV CMD", __func__);
21668 return -EINVAL;
21669 }
21670
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021671 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21672 TRACE_CODE_HDD_CFG80211_TESTMODE,
21673 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021674 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21675 {
21676#ifdef FEATURE_WLAN_LPHB
21677 /* Low Power Heartbeat configuration request */
21678 case WLAN_HDD_TM_CMD_WLAN_HB:
21679 {
21680 int buf_len;
21681 void *buf;
21682 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021683 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021684
21685 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21686 {
21687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21688 "%s Testmode INV DATA", __func__);
21689 return -EINVAL;
21690 }
21691
21692 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21693 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021694
Manjeet Singh3c577442017-02-10 19:03:38 +053021695 if (buf_len > sizeof(*hb_params)) {
21696 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21697 buf_len);
21698 return -ERANGE;
21699 }
21700
Amar Singhal05852702014-02-04 14:40:00 -080021701 hb_params_temp =(tSirLPHBReq *)buf;
21702 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21703 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21704 return -EINVAL;
21705
Leo Chang9056f462013-08-01 19:21:11 -070021706 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21707 if (NULL == hb_params)
21708 {
21709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21710 "%s Request Buffer Alloc Fail", __func__);
21711 return -EINVAL;
21712 }
21713
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021714 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021715 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021716 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21717 hb_params,
21718 wlan_hdd_cfg80211_lphb_ind_handler);
21719 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021720 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21722 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021723 vos_mem_free(hb_params);
21724 }
Leo Chang9056f462013-08-01 19:21:11 -070021725 return 0;
21726 }
21727#endif /* FEATURE_WLAN_LPHB */
21728 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21730 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021731 return -EOPNOTSUPP;
21732 }
21733
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021734 EXIT();
21735 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021736}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021737
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021738static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21740 struct wireless_dev *wdev,
21741#endif
21742 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021743{
21744 int ret;
21745
21746 vos_ssr_protect(__func__);
21747 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21748 vos_ssr_unprotect(__func__);
21749
21750 return ret;
21751}
Leo Chang9056f462013-08-01 19:21:11 -070021752#endif /* CONFIG_NL80211_TESTMODE */
21753
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021754extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021755static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021756 struct net_device *dev,
21757 int idx, struct survey_info *survey)
21758{
21759 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21760 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021761 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021762 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021763 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021764 v_S7_t snr,rssi;
21765 int status, i, j, filled = 0;
21766
21767 ENTER();
21768
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021769 if (NULL == pAdapter)
21770 {
21771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21772 "%s: HDD adapter is Null", __func__);
21773 return -ENODEV;
21774 }
21775
21776 if (NULL == wiphy)
21777 {
21778 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21779 "%s: wiphy is Null", __func__);
21780 return -ENODEV;
21781 }
21782
21783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21784 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021785 if (0 != status)
21786 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021787 return status;
21788 }
21789
Mihir Sheted9072e02013-08-21 17:02:29 +053021790 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21791
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021792 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021793 0 != pAdapter->survey_idx ||
21794 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021795 {
21796 /* The survey dump ops when implemented completely is expected to
21797 * return a survey of all channels and the ops is called by the
21798 * kernel with incremental values of the argument 'idx' till it
21799 * returns -ENONET. But we can only support the survey for the
21800 * operating channel for now. survey_idx is used to track
21801 * that the ops is called only once and then return -ENONET for
21802 * the next iteration
21803 */
21804 pAdapter->survey_idx = 0;
21805 return -ENONET;
21806 }
21807
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021808 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21809 {
21810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21811 "%s: Roaming in progress, hence return ", __func__);
21812 return -ENONET;
21813 }
21814
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021815 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21816
21817 wlan_hdd_get_snr(pAdapter, &snr);
21818 wlan_hdd_get_rssi(pAdapter, &rssi);
21819
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021820 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21821 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21822 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021823 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21824 hdd_wlan_get_freq(channel, &freq);
21825
21826
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021827 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021828 {
21829 if (NULL == wiphy->bands[i])
21830 {
21831 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21832 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21833 continue;
21834 }
21835
21836 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21837 {
21838 struct ieee80211_supported_band *band = wiphy->bands[i];
21839
21840 if (band->channels[j].center_freq == (v_U16_t)freq)
21841 {
21842 survey->channel = &band->channels[j];
21843 /* The Rx BDs contain SNR values in dB for the received frames
21844 * while the supplicant expects noise. So we calculate and
21845 * return the value of noise (dBm)
21846 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21847 */
21848 survey->noise = rssi - snr;
21849 survey->filled = SURVEY_INFO_NOISE_DBM;
21850 filled = 1;
21851 }
21852 }
21853 }
21854
21855 if (filled)
21856 pAdapter->survey_idx = 1;
21857 else
21858 {
21859 pAdapter->survey_idx = 0;
21860 return -ENONET;
21861 }
21862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021863 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021864 return 0;
21865}
21866
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021867static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21868 struct net_device *dev,
21869 int idx, struct survey_info *survey)
21870{
21871 int ret;
21872
21873 vos_ssr_protect(__func__);
21874 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21875 vos_ssr_unprotect(__func__);
21876
21877 return ret;
21878}
21879
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021880/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021881 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021882 * this is called when cfg80211 driver resume
21883 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21884 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021885int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021886{
21887 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21888 hdd_adapter_t *pAdapter;
21889 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21890 VOS_STATUS status = VOS_STATUS_SUCCESS;
21891
21892 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021893
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021894 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021895 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021896 return 0;
21897 }
21898
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021899 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21900 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021901
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021902 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021903 {
21904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21905 "%s: Resume SoftAP", __func__);
21906 hdd_set_wlan_suspend_mode(false);
21907 }
21908
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021909 spin_lock(&pHddCtx->schedScan_lock);
21910 pHddCtx->isWiphySuspended = FALSE;
21911 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21912 {
21913 spin_unlock(&pHddCtx->schedScan_lock);
21914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21915 "%s: Return resume is not due to PNO indication", __func__);
21916 return 0;
21917 }
21918 // Reset flag to avoid updatating cfg80211 data old results again
21919 pHddCtx->isSchedScanUpdatePending = FALSE;
21920 spin_unlock(&pHddCtx->schedScan_lock);
21921
21922 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21923
21924 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21925 {
21926 pAdapter = pAdapterNode->pAdapter;
21927 if ( (NULL != pAdapter) &&
21928 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21929 {
21930 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021931 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21933 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021934 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021935 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021936 {
21937 /* Acquire wakelock to handle the case where APP's tries to
21938 * suspend immediately after updating the scan results. Whis
21939 * results in app's is in suspended state and not able to
21940 * process the connect request to AP
21941 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021942 hdd_prevent_suspend_timeout(2000,
21943 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021944 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021945 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021946
21947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21948 "%s : cfg80211 scan result database updated", __func__);
21949
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021950 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021951 return 0;
21952
21953 }
21954 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21955 pAdapterNode = pNext;
21956 }
21957
21958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21959 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021960 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021961 return 0;
21962}
21963
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021964int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21965{
21966 int ret;
21967
21968 vos_ssr_protect(__func__);
21969 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21970 vos_ssr_unprotect(__func__);
21971
21972 return ret;
21973}
21974
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021975/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021976 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021977 * this is called when cfg80211 driver suspends
21978 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021979int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021980 struct cfg80211_wowlan *wow)
21981{
21982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021983 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021984
21985 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021986
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021987 ret = wlan_hdd_validate_context(pHddCtx);
21988 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021989 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021990 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021991 }
21992
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021993 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21995 "%s: Suspend SoftAP", __func__);
21996 hdd_set_wlan_suspend_mode(true);
21997 }
21998
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021999
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022000 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22001 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22002 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022003 pHddCtx->isWiphySuspended = TRUE;
22004
22005 EXIT();
22006
22007 return 0;
22008}
22009
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022010int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22011 struct cfg80211_wowlan *wow)
22012{
22013 int ret;
22014
22015 vos_ssr_protect(__func__);
22016 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22017 vos_ssr_unprotect(__func__);
22018
22019 return ret;
22020}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022021
22022#ifdef FEATURE_OEM_DATA_SUPPORT
22023static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022024 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022025{
22026 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22027
22028 ENTER();
22029
22030 if (wlan_hdd_validate_context(pHddCtx)) {
22031 return;
22032 }
22033 if (!pMsg)
22034 {
22035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22036 return;
22037 }
22038
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022039 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022040
22041 EXIT();
22042 return;
22043
22044}
22045
22046void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022047 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022048{
22049 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22050
22051 ENTER();
22052
22053 if (wlan_hdd_validate_context(pHddCtx)) {
22054 return;
22055 }
22056
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022057 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022058
22059 switch(evType) {
22060 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022061 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022062 break;
22063 default:
22064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22065 break;
22066 }
22067 EXIT();
22068}
22069#endif
22070
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022071#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22072 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022073/**
22074 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22075 * @wiphy: Pointer to wiphy
22076 * @wdev: Pointer to wireless device structure
22077 *
22078 * This function is used to abort an ongoing scan
22079 *
22080 * Return: None
22081 */
22082static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22083 struct wireless_dev *wdev)
22084{
22085 struct net_device *dev = wdev->netdev;
22086 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22087 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22088 int ret;
22089
22090 ENTER();
22091
22092 if (NULL == adapter) {
22093 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22094 return;
22095 }
22096
22097 ret = wlan_hdd_validate_context(hdd_ctx);
22098 if (0 != ret)
22099 return;
22100
22101 wlan_hdd_scan_abort(adapter);
22102
22103 return;
22104}
22105
22106/**
22107 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22108 * @wiphy: Pointer to wiphy
22109 * @wdev: Pointer to wireless device structure
22110 *
22111 * Return: None
22112 */
22113void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22114 struct wireless_dev *wdev)
22115{
22116 vos_ssr_protect(__func__);
22117 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22118 vos_ssr_unprotect(__func__);
22119
22120 return;
22121}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022122#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022123
Abhishek Singh936c6932017-11-07 17:28:23 +053022124#ifdef CHANNEL_SWITCH_SUPPORTED
22125/**
22126 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22127 * channel in SAP/GO
22128 * @wiphy: wiphy pointer
22129 * @dev: dev pointer.
22130 * @csa_params: Change channel params
22131 *
22132 * This function is called to switch channel in SAP/GO
22133 *
22134 * Return: 0 if success else return non zero
22135 */
22136static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22137 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22138{
22139 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22140 hdd_context_t *hdd_ctx;
22141 uint8_t channel;
22142 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022143 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022144 v_CONTEXT_t vos_ctx;
22145
22146 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22147
22148 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22149 ret = wlan_hdd_validate_context(hdd_ctx);
22150 if (ret)
22151 return ret;
22152
22153 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22154 if (!vos_ctx) {
22155 hddLog(LOGE, FL("Vos ctx is null"));
22156 return -EINVAL;
22157 }
22158
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022159 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022160 return -ENOTSUPP;
22161
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022162 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22163 if (!sap_ctx) {
22164 hddLog(LOGE, FL("sap_ctx is NULL"));
22165 return -EINVAL;
22166 }
22167
22168 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22169 if (ret)
22170 return ret;
22171
22172 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22173
Abhishek Singh936c6932017-11-07 17:28:23 +053022174 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022175 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022176
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022177 if (ret) {
22178 wlansap_reset_chan_change_in_progress(sap_ctx);
22179 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22180 }
22181
Abhishek Singh936c6932017-11-07 17:28:23 +053022182 return ret;
22183}
22184
22185/**
22186 * wlan_hdd_cfg80211_channel_switch()- function to switch
22187 * channel in SAP/GO
22188 * @wiphy: wiphy pointer
22189 * @dev: dev pointer.
22190 * @csa_params: Change channel params
22191 *
22192 * This function is called to switch channel in SAP/GO
22193 *
22194 * Return: 0 if success else return non zero
22195 */
22196static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22197 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22198{
22199 int ret;
22200
22201 vos_ssr_protect(__func__);
22202 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22203 vos_ssr_unprotect(__func__);
22204
22205 return ret;
22206}
22207#endif
22208
Jeff Johnson295189b2012-06-20 16:38:30 -070022209/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022210static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022211{
22212 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22213 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22214 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22215 .change_station = wlan_hdd_change_station,
22216#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22217 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22218 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22219 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022220#else
22221 .start_ap = wlan_hdd_cfg80211_start_ap,
22222 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22223 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022224#endif
22225 .change_bss = wlan_hdd_cfg80211_change_bss,
22226 .add_key = wlan_hdd_cfg80211_add_key,
22227 .get_key = wlan_hdd_cfg80211_get_key,
22228 .del_key = wlan_hdd_cfg80211_del_key,
22229 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022230#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022231 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022233 .scan = wlan_hdd_cfg80211_scan,
22234 .connect = wlan_hdd_cfg80211_connect,
22235 .disconnect = wlan_hdd_cfg80211_disconnect,
22236 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22237 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22238 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22239 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22240 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022241 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22242 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022243 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22245 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22246 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22247 .set_txq_params = wlan_hdd_set_txq_params,
22248#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022249 .get_station = wlan_hdd_cfg80211_get_station,
22250 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22251 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022252 .add_station = wlan_hdd_cfg80211_add_station,
22253#ifdef FEATURE_WLAN_LFR
22254 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22255 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22256 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22257#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022258#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22259 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22260#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022261#ifdef FEATURE_WLAN_TDLS
22262 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22263 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22264#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022265#ifdef WLAN_FEATURE_GTK_OFFLOAD
22266 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22267#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022268#ifdef FEATURE_WLAN_SCAN_PNO
22269 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22270 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22271#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022272 .resume = wlan_hdd_cfg80211_resume_wlan,
22273 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022274 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022275#ifdef WLAN_NL80211_TESTMODE
22276 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22277#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022278 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022279#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22280 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022281 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022282#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022283#ifdef CHANNEL_SWITCH_SUPPORTED
22284 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22285#endif
22286
Jeff Johnson295189b2012-06-20 16:38:30 -070022287};
22288