blob: d06374049178acf4e08e1369d5fa0cf31223272a [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);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301920 if(!rates)
1921 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922
1923 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1924 {
1925 hddLog(VOS_TRACE_LEVEL_ERROR,
1926 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1927 return FALSE;
1928 }
1929 nla_nest_end(vendor_event, rates);
1930 }
1931 nla_nest_end(vendor_event, rateInfo);
1932
1933 return TRUE;
1934error:
1935 return FALSE;
1936}
1937
1938static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1939 struct sk_buff *vendor_event)
1940{
1941 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1942 stats->ac ) ||
1943 nla_put_u32(vendor_event,
1944 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1945 stats->txMpdu ) ||
1946 nla_put_u32(vendor_event,
1947 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1948 stats->rxMpdu ) ||
1949 nla_put_u32(vendor_event,
1950 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1951 stats->txMcast ) ||
1952 nla_put_u32(vendor_event,
1953 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1954 stats->rxMcast ) ||
1955 nla_put_u32(vendor_event,
1956 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1957 stats->rxAmpdu ) ||
1958 nla_put_u32(vendor_event,
1959 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1960 stats->txAmpdu ) ||
1961 nla_put_u32(vendor_event,
1962 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1963 stats->mpduLost )||
1964 nla_put_u32(vendor_event,
1965 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1966 stats->retries ) ||
1967 nla_put_u32(vendor_event,
1968 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1969 stats->retriesShort ) ||
1970 nla_put_u32(vendor_event,
1971 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1972 stats->retriesLong ) ||
1973 nla_put_u32(vendor_event,
1974 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1975 stats->contentionTimeMin ) ||
1976 nla_put_u32(vendor_event,
1977 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1978 stats->contentionTimeMax ) ||
1979 nla_put_u32(vendor_event,
1980 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1981 stats->contentionTimeAvg ) ||
1982 nla_put_u32(vendor_event,
1983 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1984 stats->contentionNumSamples ))
1985 {
1986 hddLog(VOS_TRACE_LEVEL_ERROR,
1987 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1988 return FALSE;
1989 }
1990 return TRUE;
1991}
1992
1993static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1994 struct sk_buff *vendor_event)
1995{
Dino Myclec8f3f332014-07-21 16:48:27 +05301996 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1998 nla_put(vendor_event,
1999 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
2000 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2001 nla_put_u32(vendor_event,
2002 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2003 stats->state ) ||
2004 nla_put_u32(vendor_event,
2005 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2006 stats->roaming ) ||
2007 nla_put_u32(vendor_event,
2008 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2009 stats->capabilities ) ||
2010 nla_put(vendor_event,
2011 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2012 strlen(stats->ssid), stats->ssid) ||
2013 nla_put(vendor_event,
2014 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2015 WNI_CFG_BSSID_LEN, stats->bssid) ||
2016 nla_put(vendor_event,
2017 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2018 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2019 nla_put(vendor_event,
2020 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2021 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2022 )
2023 {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,
2025 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2026 return FALSE;
2027 }
2028 return TRUE;
2029}
2030
Dino Mycle3b9536d2014-07-09 22:05:24 +05302031static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2032 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033 struct sk_buff *vendor_event)
2034{
2035 int i = 0;
2036 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302037 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2038 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302039 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302040
Sunil Duttc69bccb2014-05-26 21:30:20 +05302041 if (FALSE == put_wifi_interface_info(
2042 &pWifiIfaceStat->info,
2043 vendor_event))
2044 {
2045 hddLog(VOS_TRACE_LEVEL_ERROR,
2046 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2047 return FALSE;
2048
2049 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302050 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2051 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2052 if (NULL == pWifiIfaceStatTL)
2053 {
2054 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2055 return FALSE;
2056 }
2057
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302058 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2060 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2061 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2062
2063 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2065 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302067
2068 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2069 {
2070 if (VOS_STATUS_SUCCESS ==
2071 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2072 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2073 {
2074 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2075 * obtained from TL structure
2076 */
2077
2078 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2079 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302080 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2081
Srinivas Dasari98947432014-11-07 19:41:24 +05302082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2088 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2089 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302090
Srinivas Dasari98947432014-11-07 19:41:24 +05302091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2097 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2098 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302099
Srinivas Dasari98947432014-11-07 19:41:24 +05302100 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2101 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2102 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2103 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2104 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2105 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2106 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2107 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302108 }
2109 else
2110 {
2111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2112 }
2113
Dino Mycle3b9536d2014-07-09 22:05:24 +05302114 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2115 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2116 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2117 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2118 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2119 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2120 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2121 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2122 }
2123 else
2124 {
2125 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2126 }
2127
2128
Sunil Duttc69bccb2014-05-26 21:30:20 +05302129
2130 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302131 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2132 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2133 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2135 pWifiIfaceStat->beaconRx) ||
2136 nla_put_u32(vendor_event,
2137 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2138 pWifiIfaceStat->mgmtRx) ||
2139 nla_put_u32(vendor_event,
2140 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2141 pWifiIfaceStat->mgmtActionRx) ||
2142 nla_put_u32(vendor_event,
2143 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2144 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302145 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302146 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2147 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302148 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302149 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2150 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302151 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302152 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2153 pWifiIfaceStat->rssiAck))
2154 {
2155 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302156 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2157 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302158 return FALSE;
2159 }
2160
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302161#ifdef FEATURE_EXT_LL_STAT
2162 /*
2163 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2164 * then host should send Leaky AP stats to upper layer,
2165 * otherwise no need to send these stats.
2166 */
2167 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2168 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2169 )
2170 {
2171 hddLog(VOS_TRACE_LEVEL_INFO,
2172 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2173 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2174 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2175 pWifiIfaceStat->leakyApStat.rx_leak_window,
2176 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2177 if (nla_put_u32(vendor_event,
2178 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2179 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2180 nla_put_u32(vendor_event,
2181 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2182 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2183 nla_put_u32(vendor_event,
2184 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2185 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302186 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302187 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2188 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2189 {
2190 hddLog(VOS_TRACE_LEVEL_ERROR,
2191 FL("EXT_LL_STAT put fail"));
2192 vos_mem_free(pWifiIfaceStatTL);
2193 return FALSE;
2194 }
2195 }
2196#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302197 wmmInfo = nla_nest_start(vendor_event,
2198 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302199 if(!wmmInfo)
2200 {
2201 vos_mem_free(pWifiIfaceStatTL);
2202 return FALSE;
2203 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302204 for (i = 0; i < WIFI_AC_MAX; i++)
2205 {
2206 struct nlattr *wmmStats;
2207 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302208 if(!wmmStats)
2209 {
2210 vos_mem_free(pWifiIfaceStatTL);
2211 return FALSE;
2212 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302213 if (FALSE == put_wifi_wmm_ac_stat(
2214 &pWifiIfaceStat->AccessclassStats[i],
2215 vendor_event))
2216 {
2217 hddLog(VOS_TRACE_LEVEL_ERROR,
2218 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302219 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302220 return FALSE;
2221 }
2222
2223 nla_nest_end(vendor_event, wmmStats);
2224 }
2225 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302226 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 return TRUE;
2228}
2229
2230static tSirWifiInterfaceMode
2231 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2232{
2233 switch (deviceMode)
2234 {
2235 case WLAN_HDD_INFRA_STATION:
2236 return WIFI_INTERFACE_STA;
2237 case WLAN_HDD_SOFTAP:
2238 return WIFI_INTERFACE_SOFTAP;
2239 case WLAN_HDD_P2P_CLIENT:
2240 return WIFI_INTERFACE_P2P_CLIENT;
2241 case WLAN_HDD_P2P_GO:
2242 return WIFI_INTERFACE_P2P_GO;
2243 case WLAN_HDD_IBSS:
2244 return WIFI_INTERFACE_IBSS;
2245 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302246 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302247 }
2248}
2249
2250static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2251 tpSirWifiInterfaceInfo pInfo)
2252{
2253 v_U8_t *staMac = NULL;
2254 hdd_station_ctx_t *pHddStaCtx;
2255 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2256 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2257
2258 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2259
2260 vos_mem_copy(pInfo->macAddr,
2261 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2262
2263 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2264 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2265 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2266 {
2267 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2268 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2269 {
2270 pInfo->state = WIFI_DISCONNECTED;
2271 }
2272 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2273 {
2274 hddLog(VOS_TRACE_LEVEL_ERROR,
2275 "%s: Session ID %d, Connection is in progress", __func__,
2276 pAdapter->sessionId);
2277 pInfo->state = WIFI_ASSOCIATING;
2278 }
2279 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2280 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2281 {
2282 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2283 hddLog(VOS_TRACE_LEVEL_ERROR,
2284 "%s: client " MAC_ADDRESS_STR
2285 " is in the middle of WPS/EAPOL exchange.", __func__,
2286 MAC_ADDR_ARRAY(staMac));
2287 pInfo->state = WIFI_AUTHENTICATING;
2288 }
2289 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2290 {
2291 pInfo->state = WIFI_ASSOCIATED;
2292 vos_mem_copy(pInfo->bssid,
2293 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2294 vos_mem_copy(pInfo->ssid,
2295 pHddStaCtx->conn_info.SSID.SSID.ssId,
2296 pHddStaCtx->conn_info.SSID.SSID.length);
2297 //NULL Terminate the string.
2298 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2299 }
2300 }
2301 vos_mem_copy(pInfo->countryStr,
2302 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2303
2304 vos_mem_copy(pInfo->apCountryStr,
2305 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2306
2307 return TRUE;
2308}
2309
2310/*
2311 * hdd_link_layer_process_peer_stats () - This function is called after
2312 * receiving Link Layer Peer statistics from FW.This function converts
2313 * the firmware data to the NL data and sends the same to the kernel/upper
2314 * layers.
2315 */
2316static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2317 v_VOID_t *pData)
2318{
2319 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 tpSirWifiPeerStat pWifiPeerStat;
2321 tpSirWifiPeerInfo pWifiPeerInfo;
2322 struct nlattr *peerInfo;
2323 struct sk_buff *vendor_event;
2324 int status, i;
2325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302326 ENTER();
2327
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 status = wlan_hdd_validate_context(pHddCtx);
2329 if (0 != status)
2330 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302331 return;
2332 }
2333
2334 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2335
2336 hddLog(VOS_TRACE_LEVEL_INFO,
2337 "LL_STATS_PEER_ALL : numPeers %u",
2338 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 /*
2340 * Allocate a size of 4096 for the peer stats comprising
2341 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2342 * sizeof (tSirWifiRateStat).Each field is put with an
2343 * NL attribute.The size of 4096 is considered assuming
2344 * that number of rates shall not exceed beyond 50 with
2345 * the sizeof (tSirWifiRateStat) being 32.
2346 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302347 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2348 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302349 if (!vendor_event)
2350 {
2351 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302352 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302353 __func__);
2354 return;
2355 }
2356 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302357 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2358 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2359 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302360 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2361 pWifiPeerStat->numPeers))
2362 {
2363 hddLog(VOS_TRACE_LEVEL_ERROR,
2364 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2365 kfree_skb(vendor_event);
2366 return;
2367 }
2368
2369 peerInfo = nla_nest_start(vendor_event,
2370 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302371 if(!peerInfo)
2372 {
2373 hddLog(VOS_TRACE_LEVEL_ERROR,
2374 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2375 __func__);
2376 kfree_skb(vendor_event);
2377 return;
2378 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302379
2380 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2381 pWifiPeerStat->peerInfo);
2382
2383 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2384 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302386 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302387
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302388 if(!peers)
2389 {
2390 hddLog(VOS_TRACE_LEVEL_ERROR,
2391 "%s: peer stats put fail",
2392 __func__);
2393 kfree_skb(vendor_event);
2394 return;
2395 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302396 if (FALSE == put_wifi_peer_info(
2397 pWifiPeerInfo, vendor_event))
2398 {
2399 hddLog(VOS_TRACE_LEVEL_ERROR,
2400 "%s: put_wifi_peer_info put fail", __func__);
2401 kfree_skb(vendor_event);
2402 return;
2403 }
2404
2405 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2406 pWifiPeerStat->peerInfo +
2407 (i * sizeof(tSirWifiPeerInfo)) +
2408 (numRate * sizeof (tSirWifiRateStat)));
2409 nla_nest_end(vendor_event, peers);
2410 }
2411 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302412 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302413 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302414}
2415
2416/*
2417 * hdd_link_layer_process_iface_stats () - This function is called after
2418 * receiving Link Layer Interface statistics from FW.This function converts
2419 * the firmware data to the NL data and sends the same to the kernel/upper
2420 * layers.
2421 */
2422static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2423 v_VOID_t *pData)
2424{
2425 tpSirWifiIfaceStat pWifiIfaceStat;
2426 struct sk_buff *vendor_event;
2427 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2428 int status;
2429
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302430 ENTER();
2431
Sunil Duttc69bccb2014-05-26 21:30:20 +05302432 status = wlan_hdd_validate_context(pHddCtx);
2433 if (0 != status)
2434 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 return;
2436 }
2437 /*
2438 * Allocate a size of 4096 for the interface stats comprising
2439 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2440 * assuming that all these fit with in the limit.Please take
2441 * a call on the limit based on the data requirements on
2442 * interface statistics.
2443 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302444 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2445 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302446 if (!vendor_event)
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302449 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302450 return;
2451 }
2452
2453 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2454
Dino Mycle3b9536d2014-07-09 22:05:24 +05302455
2456 if (FALSE == hdd_get_interface_info( pAdapter,
2457 &pWifiIfaceStat->info))
2458 {
2459 hddLog(VOS_TRACE_LEVEL_ERROR,
2460 FL("hdd_get_interface_info get fail") );
2461 kfree_skb(vendor_event);
2462 return;
2463 }
2464
2465 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2466 vendor_event))
2467 {
2468 hddLog(VOS_TRACE_LEVEL_ERROR,
2469 FL("put_wifi_iface_stats fail") );
2470 kfree_skb(vendor_event);
2471 return;
2472 }
2473
Sunil Duttc69bccb2014-05-26 21:30:20 +05302474 hddLog(VOS_TRACE_LEVEL_INFO,
2475 "WMI_LINK_STATS_IFACE Data");
2476
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302477 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302478
2479 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302480}
2481
2482/*
2483 * hdd_link_layer_process_radio_stats () - This function is called after
2484 * receiving Link Layer Radio statistics from FW.This function converts
2485 * the firmware data to the NL data and sends the same to the kernel/upper
2486 * layers.
2487 */
2488static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2489 v_VOID_t *pData)
2490{
2491 int status, i;
2492 tpSirWifiRadioStat pWifiRadioStat;
2493 tpSirWifiChannelStats pWifiChannelStats;
2494 struct sk_buff *vendor_event;
2495 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2496 struct nlattr *chList;
2497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302498 ENTER();
2499
Sunil Duttc69bccb2014-05-26 21:30:20 +05302500 status = wlan_hdd_validate_context(pHddCtx);
2501 if (0 != status)
2502 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302503 return;
2504 }
2505 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2506
2507 hddLog(VOS_TRACE_LEVEL_INFO,
2508 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302509 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 " radio is %d onTime is %u "
2511 " txTime is %u rxTime is %u "
2512 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302513 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302514 " onTimePnoScan is %u onTimeHs20 is %u "
2515 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302516 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302517 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2518 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2519 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302520 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302521 pWifiRadioStat->onTimeRoamScan,
2522 pWifiRadioStat->onTimePnoScan,
2523 pWifiRadioStat->onTimeHs20,
2524 pWifiRadioStat->numChannels);
2525 /*
2526 * Allocate a size of 4096 for the Radio stats comprising
2527 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2528 * (tSirWifiChannelStats).Each channel data is put with an
2529 * NL attribute.The size of 4096 is considered assuming that
2530 * number of channels shall not exceed beyond 60 with the
2531 * sizeof (tSirWifiChannelStats) being 24 bytes.
2532 */
2533
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302534 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2535 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 if (!vendor_event)
2537 {
2538 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302539 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302540 return;
2541 }
2542
2543 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302544 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2545 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2546 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302547 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2548 pWifiRadioStat->radio) ||
2549 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302550 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2551 NUM_RADIOS) ||
2552 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302553 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2554 pWifiRadioStat->onTime) ||
2555 nla_put_u32(vendor_event,
2556 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2557 pWifiRadioStat->txTime) ||
2558 nla_put_u32(vendor_event,
2559 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2560 pWifiRadioStat->rxTime) ||
2561 nla_put_u32(vendor_event,
2562 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2563 pWifiRadioStat->onTimeScan) ||
2564 nla_put_u32(vendor_event,
2565 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2566 pWifiRadioStat->onTimeNbd) ||
2567 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302568 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2569 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302570 nla_put_u32(vendor_event,
2571 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2572 pWifiRadioStat->onTimeRoamScan) ||
2573 nla_put_u32(vendor_event,
2574 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2575 pWifiRadioStat->onTimePnoScan) ||
2576 nla_put_u32(vendor_event,
2577 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2578 pWifiRadioStat->onTimeHs20) ||
2579 nla_put_u32(vendor_event,
2580 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2581 pWifiRadioStat->numChannels))
2582 {
2583 hddLog(VOS_TRACE_LEVEL_ERROR,
2584 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2585 kfree_skb(vendor_event);
2586 return ;
2587 }
2588
2589 chList = nla_nest_start(vendor_event,
2590 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302591 if(!chList)
2592 {
2593 hddLog(VOS_TRACE_LEVEL_ERROR,
2594 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2595 __func__);
2596 kfree_skb(vendor_event);
2597 return;
2598 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302599 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2600 {
2601 struct nlattr *chInfo;
2602
2603 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2604 pWifiRadioStat->channels +
2605 (i * sizeof(tSirWifiChannelStats)));
2606
Sunil Duttc69bccb2014-05-26 21:30:20 +05302607 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302608 if(!chInfo)
2609 {
2610 hddLog(VOS_TRACE_LEVEL_ERROR,
2611 "%s: failed to put chInfo",
2612 __func__);
2613 kfree_skb(vendor_event);
2614 return;
2615 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302616
2617 if (nla_put_u32(vendor_event,
2618 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2619 pWifiChannelStats->channel.width) ||
2620 nla_put_u32(vendor_event,
2621 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2622 pWifiChannelStats->channel.centerFreq) ||
2623 nla_put_u32(vendor_event,
2624 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2625 pWifiChannelStats->channel.centerFreq0) ||
2626 nla_put_u32(vendor_event,
2627 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2628 pWifiChannelStats->channel.centerFreq1) ||
2629 nla_put_u32(vendor_event,
2630 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2631 pWifiChannelStats->onTime) ||
2632 nla_put_u32(vendor_event,
2633 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2634 pWifiChannelStats->ccaBusyTime))
2635 {
2636 hddLog(VOS_TRACE_LEVEL_ERROR,
2637 FL("cfg80211_vendor_event_alloc failed") );
2638 kfree_skb(vendor_event);
2639 return ;
2640 }
2641 nla_nest_end(vendor_event, chInfo);
2642 }
2643 nla_nest_end(vendor_event, chList);
2644
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302645 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302646
2647 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648 return;
2649}
2650
2651/*
2652 * hdd_link_layer_stats_ind_callback () - This function is called after
2653 * receiving Link Layer indications from FW.This callback converts the firmware
2654 * data to the NL data and send the same to the kernel/upper layers.
2655 */
2656static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2657 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302658 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302659{
Dino Mycled3d50022014-07-07 12:58:25 +05302660 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2661 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302662 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302663 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302664 int status;
2665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302666 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302668 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302669 if (0 != status)
2670 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302671 return;
2672 }
2673
Dino Mycled3d50022014-07-07 12:58:25 +05302674 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2675 if (NULL == pAdapter)
2676 {
2677 hddLog(VOS_TRACE_LEVEL_ERROR,
2678 FL(" MAC address %pM does not exist with host"),
2679 macAddr);
2680 return;
2681 }
2682
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302684 "%s: Interface: %s LLStats indType: %d", __func__,
2685 pAdapter->dev->name, indType);
2686
Sunil Duttc69bccb2014-05-26 21:30:20 +05302687 switch (indType)
2688 {
2689 case SIR_HAL_LL_STATS_RESULTS_RSP:
2690 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302691 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302692 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2693 "respId = %u, moreResultToFollow = %u",
2694 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2695 macAddr, linkLayerStatsResults->respId,
2696 linkLayerStatsResults->moreResultToFollow);
2697
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302698 spin_lock(&hdd_context_lock);
2699 context = &pHddCtx->ll_stats_context;
2700 /* validate response received from target */
2701 if ((context->request_id != linkLayerStatsResults->respId) ||
2702 !(context->request_bitmap & linkLayerStatsResults->paramId))
2703 {
2704 spin_unlock(&hdd_context_lock);
2705 hddLog(LOGE,
2706 FL("Error : Request id %d response id %d request bitmap 0x%x"
2707 "response bitmap 0x%x"),
2708 context->request_id, linkLayerStatsResults->respId,
2709 context->request_bitmap, linkLayerStatsResults->paramId);
2710 return;
2711 }
2712 spin_unlock(&hdd_context_lock);
2713
Sunil Duttc69bccb2014-05-26 21:30:20 +05302714 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2715 {
2716 hdd_link_layer_process_radio_stats(pAdapter,
2717 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302718 spin_lock(&hdd_context_lock);
2719 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2720 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302721 }
2722 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2723 {
2724 hdd_link_layer_process_iface_stats(pAdapter,
2725 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302726 spin_lock(&hdd_context_lock);
2727 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2728 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302729 }
2730 else if ( linkLayerStatsResults->paramId &
2731 WMI_LINK_STATS_ALL_PEER )
2732 {
2733 hdd_link_layer_process_peer_stats(pAdapter,
2734 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302735 spin_lock(&hdd_context_lock);
2736 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2737 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302738 } /* WMI_LINK_STATS_ALL_PEER */
2739 else
2740 {
2741 hddLog(VOS_TRACE_LEVEL_ERROR,
2742 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2743 }
2744
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302745 spin_lock(&hdd_context_lock);
2746 /* complete response event if all requests are completed */
2747 if (0 == context->request_bitmap)
2748 complete(&context->response_event);
2749 spin_unlock(&hdd_context_lock);
2750
Sunil Duttc69bccb2014-05-26 21:30:20 +05302751 break;
2752 }
2753 default:
2754 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2755 break;
2756 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302757
2758 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302759 return;
2760}
2761
2762const struct
2763nla_policy
2764qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2765{
2766 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2767 { .type = NLA_U32 },
2768 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2769 { .type = NLA_U32 },
2770};
2771
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302772static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2773 struct wireless_dev *wdev,
2774 const void *data,
2775 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302776{
2777 int status;
2778 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302779 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302780 struct net_device *dev = wdev->netdev;
2781 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2782 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2783
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302784 ENTER();
2785
Sunil Duttc69bccb2014-05-26 21:30:20 +05302786 status = wlan_hdd_validate_context(pHddCtx);
2787 if (0 != status)
2788 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302789 return -EINVAL;
2790 }
2791
2792 if (NULL == pAdapter)
2793 {
2794 hddLog(VOS_TRACE_LEVEL_ERROR,
2795 FL("HDD adapter is Null"));
2796 return -ENODEV;
2797 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302798 /* check the LLStats Capability */
2799 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2800 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2801 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302802 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302803 FL("Link Layer Statistics not supported by Firmware"));
2804 return -EINVAL;
2805 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302806
2807 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2808 (struct nlattr *)data,
2809 data_len, qca_wlan_vendor_ll_set_policy))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2812 return -EINVAL;
2813 }
2814 if (!tb_vendor
2815 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2816 {
2817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2818 return -EINVAL;
2819 }
2820 if (!tb_vendor[
2821 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2822 {
2823 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2824 return -EINVAL;
2825 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302826 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302827 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828
Dino Mycledf0a5d92014-07-04 09:41:55 +05302829 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302830 nla_get_u32(
2831 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2832
Dino Mycledf0a5d92014-07-04 09:41:55 +05302833 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302834 nla_get_u32(
2835 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2836
Dino Mycled3d50022014-07-07 12:58:25 +05302837 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2838 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302839
2840
2841 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302842 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2843 "Statistics Gathering = %d ",
2844 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2845 linkLayerStatsSetReq.mpduSizeThreshold,
2846 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847
2848 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2849 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302850 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302851 {
2852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2853 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302854 return -EINVAL;
2855
2856 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302857
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302859 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302860 {
2861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2862 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302863 return -EINVAL;
2864 }
2865
2866 pAdapter->isLinkLayerStatsSet = 1;
2867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302868 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302869 return 0;
2870}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302871static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2872 struct wireless_dev *wdev,
2873 const void *data,
2874 int data_len)
2875{
2876 int ret = 0;
2877
2878 vos_ssr_protect(__func__);
2879 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2880 vos_ssr_unprotect(__func__);
2881
2882 return ret;
2883}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302884
2885const struct
2886nla_policy
2887qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2888{
2889 /* Unsigned 32bit value provided by the caller issuing the GET stats
2890 * command. When reporting
2891 * the stats results, the driver uses the same value to indicate
2892 * which GET request the results
2893 * correspond to.
2894 */
2895 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2896
2897 /* Unsigned 32bit value . bit mask to identify what statistics are
2898 requested for retrieval */
2899 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2900};
2901
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302902static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2903 struct wireless_dev *wdev,
2904 const void *data,
2905 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302906{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302907 unsigned long rc;
2908 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302909 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2910 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302911 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302912 struct net_device *dev = wdev->netdev;
2913 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302914 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302915 int status;
2916
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302917 ENTER();
2918
Sunil Duttc69bccb2014-05-26 21:30:20 +05302919 status = wlan_hdd_validate_context(pHddCtx);
2920 if (0 != status)
2921 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302922 return -EINVAL ;
2923 }
2924
2925 if (NULL == pAdapter)
2926 {
2927 hddLog(VOS_TRACE_LEVEL_FATAL,
2928 "%s: HDD adapter is Null", __func__);
2929 return -ENODEV;
2930 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302931
2932 if (pHddStaCtx == NULL)
2933 {
2934 hddLog(VOS_TRACE_LEVEL_FATAL,
2935 "%s: HddStaCtx is Null", __func__);
2936 return -ENODEV;
2937 }
2938
Dino Mycledf0a5d92014-07-04 09:41:55 +05302939 /* check the LLStats Capability */
2940 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2941 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2942 {
2943 hddLog(VOS_TRACE_LEVEL_ERROR,
2944 FL("Link Layer Statistics not supported by Firmware"));
2945 return -EINVAL;
2946 }
2947
Sunil Duttc69bccb2014-05-26 21:30:20 +05302948
2949 if (!pAdapter->isLinkLayerStatsSet)
2950 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302951 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302952 "%s: isLinkLayerStatsSet : %d",
2953 __func__, pAdapter->isLinkLayerStatsSet);
2954 return -EINVAL;
2955 }
2956
Mukul Sharma10313ba2015-07-29 19:14:39 +05302957 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2958 {
2959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2960 "%s: Roaming in progress, so unable to proceed this request", __func__);
2961 return -EBUSY;
2962 }
2963
Sunil Duttc69bccb2014-05-26 21:30:20 +05302964 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2965 (struct nlattr *)data,
2966 data_len, qca_wlan_vendor_ll_get_policy))
2967 {
2968 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2969 return -EINVAL;
2970 }
2971
2972 if (!tb_vendor
2973 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2974 {
2975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2976 return -EINVAL;
2977 }
2978
2979 if (!tb_vendor
2980 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2981 {
2982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2983 return -EINVAL;
2984 }
2985
Sunil Duttc69bccb2014-05-26 21:30:20 +05302986
Dino Mycledf0a5d92014-07-04 09:41:55 +05302987 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302988 nla_get_u32( tb_vendor[
2989 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302990 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302991 nla_get_u32( tb_vendor[
2992 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2993
Dino Mycled3d50022014-07-07 12:58:25 +05302994 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2995 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302996
2997 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302998 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2999 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303000 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303001
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303002 spin_lock(&hdd_context_lock);
3003 context = &pHddCtx->ll_stats_context;
3004 context->request_id = linkLayerStatsGetReq.reqId;
3005 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3006 INIT_COMPLETION(context->response_event);
3007 spin_unlock(&hdd_context_lock);
3008
Sunil Duttc69bccb2014-05-26 21:30:20 +05303009 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303010 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303011 {
3012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3013 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303014 return -EINVAL;
3015 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303016
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303017 rc = wait_for_completion_timeout(&context->response_event,
3018 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3019 if (!rc)
3020 {
3021 hddLog(LOGE,
3022 FL("Target response timed out request id %d request bitmap 0x%x"),
3023 context->request_id, context->request_bitmap);
3024 return -ETIMEDOUT;
3025 }
3026
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303027 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303028 return 0;
3029}
3030
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303031static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3032 struct wireless_dev *wdev,
3033 const void *data,
3034 int data_len)
3035{
3036 int ret = 0;
3037
3038 vos_ssr_protect(__func__);
3039 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3040 vos_ssr_unprotect(__func__);
3041
3042 return ret;
3043}
3044
Sunil Duttc69bccb2014-05-26 21:30:20 +05303045const struct
3046nla_policy
3047qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3048{
3049 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3051 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3052 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3053};
3054
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303055static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3056 struct wireless_dev *wdev,
3057 const void *data,
3058 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303059{
3060 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3061 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303062 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303063 struct net_device *dev = wdev->netdev;
3064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3065 u32 statsClearReqMask;
3066 u8 stopReq;
3067 int status;
3068
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303069 ENTER();
3070
Sunil Duttc69bccb2014-05-26 21:30:20 +05303071 status = wlan_hdd_validate_context(pHddCtx);
3072 if (0 != status)
3073 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303074 return -EINVAL;
3075 }
3076
3077 if (NULL == pAdapter)
3078 {
3079 hddLog(VOS_TRACE_LEVEL_FATAL,
3080 "%s: HDD adapter is Null", __func__);
3081 return -ENODEV;
3082 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303083 /* check the LLStats Capability */
3084 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3085 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3086 {
3087 hddLog(VOS_TRACE_LEVEL_ERROR,
3088 FL("Enable LLStats Capability"));
3089 return -EINVAL;
3090 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303091
3092 if (!pAdapter->isLinkLayerStatsSet)
3093 {
3094 hddLog(VOS_TRACE_LEVEL_FATAL,
3095 "%s: isLinkLayerStatsSet : %d",
3096 __func__, pAdapter->isLinkLayerStatsSet);
3097 return -EINVAL;
3098 }
3099
3100 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3101 (struct nlattr *)data,
3102 data_len, qca_wlan_vendor_ll_clr_policy))
3103 {
3104 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3105 return -EINVAL;
3106 }
3107
3108 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3109
3110 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3111 {
3112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3113 return -EINVAL;
3114
3115 }
3116
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117
Dino Mycledf0a5d92014-07-04 09:41:55 +05303118 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303119 nla_get_u32(
3120 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3121
Dino Mycledf0a5d92014-07-04 09:41:55 +05303122 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303123 nla_get_u8(
3124 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3125
3126 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303127 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303128
Dino Mycled3d50022014-07-07 12:58:25 +05303129 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3130 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303131
3132 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303133 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3134 "statsClearReqMask = 0x%X, stopReq = %d",
3135 linkLayerStatsClearReq.reqId,
3136 linkLayerStatsClearReq.macAddr,
3137 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303138 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303139
3140 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303141 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303142 {
3143 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303144 hdd_station_ctx_t *pHddStaCtx;
3145
3146 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3147 if (VOS_STATUS_SUCCESS !=
3148 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3149 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3150 {
3151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3152 "WLANTL_ClearInterfaceStats Failed", __func__);
3153 return -EINVAL;
3154 }
3155 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3156 (statsClearReqMask & WIFI_STATS_IFACE)) {
3157 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3159 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3160 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3161 }
3162
Sunil Duttc69bccb2014-05-26 21:30:20 +05303163 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3164 2 * sizeof(u32) +
3165 NLMSG_HDRLEN);
3166
3167 if (temp_skbuff != NULL)
3168 {
3169
3170 if (nla_put_u32(temp_skbuff,
3171 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3172 statsClearReqMask) ||
3173 nla_put_u32(temp_skbuff,
3174 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3175 stopReq))
3176 {
3177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3178 kfree_skb(temp_skbuff);
3179 return -EINVAL;
3180 }
3181 /* If the ask is to stop the stats collection as part of clear
3182 * (stopReq = 1) , ensure that no further requests of get
3183 * go to the firmware by having isLinkLayerStatsSet set to 0.
3184 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303185 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303186 * case the firmware is just asked to clear the statistics.
3187 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303188 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303189 pAdapter->isLinkLayerStatsSet = 0;
3190 return cfg80211_vendor_cmd_reply(temp_skbuff);
3191 }
3192 return -ENOMEM;
3193 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303194
3195 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303196 return -EINVAL;
3197}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303198static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3199 struct wireless_dev *wdev,
3200 const void *data,
3201 int data_len)
3202{
3203 int ret = 0;
3204
3205 vos_ssr_protect(__func__);
3206 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3207 vos_ssr_unprotect(__func__);
3208
3209 return ret;
3210
3211
3212}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303213#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3214
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215#ifdef WLAN_FEATURE_EXTSCAN
3216static const struct nla_policy
3217wlan_hdd_extscan_config_policy
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3219{
3220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3221 { .type = NLA_U32 },
3222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3223 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3225 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3228 { .type = NLA_U32 },
3229 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3231
3232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3236 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303237 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3238 { .type = NLA_U32 },
3239 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3240 { .type = NLA_U32 },
3241 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3242 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303243 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3244 { .type = NLA_U32 },
3245 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3246 { .type = NLA_U32 },
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3248 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3250 { .type = NLA_U8 },
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 { .type = NLA_U8 },
3253 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3254 { .type = NLA_U8 },
3255 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3256 { .type = NLA_U8 },
3257
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3259 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3261 .type = NLA_UNSPEC,
3262 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303263 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3264 { .type = NLA_S32 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3266 { .type = NLA_S32 },
3267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3268 { .type = NLA_U32 },
3269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3270 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3272 { .type = NLA_U32 },
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3274 { .type = NLA_BINARY,
3275 .len = IEEE80211_MAX_SSID_LEN + 1 },
3276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3279 { .type = NLA_U32 },
3280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3281 { .type = NLA_U8 },
3282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3283 { .type = NLA_S32 },
3284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3285 { .type = NLA_S32 },
3286 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3287 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288};
3289
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303290/**
3291 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3292 * @ctx: hdd global context
3293 * @data: capabilities data
3294 *
3295 * Return: none
3296 */
3297static void
3298wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303300 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303301 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303302 tSirEXTScanCapabilitiesEvent *data =
3303 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303304
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303305 ENTER();
3306
3307 if (wlan_hdd_validate_context(pHddCtx))
3308 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303309 return;
3310 }
3311
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303312 if (!pMsg)
3313 {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3315 return;
3316 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303318 vos_spin_lock_acquire(&hdd_context_lock);
3319
3320 context = &pHddCtx->ext_scan_context;
3321 /* validate response received from target*/
3322 if (context->request_id != data->requestId)
3323 {
3324 vos_spin_lock_release(&hdd_context_lock);
3325 hddLog(LOGE,
3326 FL("Target response id did not match: request_id %d resposne_id %d"),
3327 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303328 return;
3329 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303330 else
3331 {
3332 context->capability_response = *data;
3333 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303334 }
3335
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303336 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303337
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338 return;
3339}
3340
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303341/*
3342 * define short names for the global vendor params
3343 * used by wlan_hdd_send_ext_scan_capability()
3344 */
3345#define PARAM_REQUEST_ID \
3346 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3347#define PARAM_STATUS \
3348 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3349#define MAX_SCAN_CACHE_SIZE \
3350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3351#define MAX_SCAN_BUCKETS \
3352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3353#define MAX_AP_CACHE_PER_SCAN \
3354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3355#define MAX_RSSI_SAMPLE_SIZE \
3356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3357#define MAX_SCAN_RPT_THRHOLD \
3358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3359#define MAX_HOTLIST_BSSIDS \
3360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3361#define MAX_BSSID_HISTORY_ENTRIES \
3362 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3363#define MAX_HOTLIST_SSIDS \
3364 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303365#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303367
3368static int wlan_hdd_send_ext_scan_capability(void *ctx)
3369{
3370 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3371 struct sk_buff *skb = NULL;
3372 int ret;
3373 tSirEXTScanCapabilitiesEvent *data;
3374 tANI_U32 nl_buf_len;
3375
3376 ret = wlan_hdd_validate_context(pHddCtx);
3377 if (0 != ret)
3378 {
3379 return ret;
3380 }
3381
3382 data = &(pHddCtx->ext_scan_context.capability_response);
3383
3384 nl_buf_len = NLMSG_HDRLEN;
3385 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3386 (sizeof(data->status) + NLA_HDRLEN) +
3387 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3388 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3389 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3390 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3391 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3392 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3393 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3394 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3395
3396 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3397
3398 if (!skb)
3399 {
3400 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3401 return -ENOMEM;
3402 }
3403
3404 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3405 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3406 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3407 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3408 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3409 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3410 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3411 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3412
3413 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3414 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3415 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3416 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3417 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3418 data->maxApPerScan) ||
3419 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3420 data->maxRssiSampleSize) ||
3421 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3422 data->maxScanReportingThreshold) ||
3423 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3424 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3425 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303426 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3427 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303428 {
3429 hddLog(LOGE, FL("nla put fail"));
3430 goto nla_put_failure;
3431 }
3432
3433 cfg80211_vendor_cmd_reply(skb);
3434 return 0;
3435
3436nla_put_failure:
3437 kfree_skb(skb);
3438 return -EINVAL;;
3439}
3440
3441/*
3442 * done with short names for the global vendor params
3443 * used by wlan_hdd_send_ext_scan_capability()
3444 */
3445#undef PARAM_REQUEST_ID
3446#undef PARAM_STATUS
3447#undef MAX_SCAN_CACHE_SIZE
3448#undef MAX_SCAN_BUCKETS
3449#undef MAX_AP_CACHE_PER_SCAN
3450#undef MAX_RSSI_SAMPLE_SIZE
3451#undef MAX_SCAN_RPT_THRHOLD
3452#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303453#undef MAX_BSSID_HISTORY_ENTRIES
3454#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
3456static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3457{
3458 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3459 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303461 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303463 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303465 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303466 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303468 if (!pMsg)
3469 {
3470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 return;
3472 }
3473
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3475 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3476
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303477 context = &pHddCtx->ext_scan_context;
3478 spin_lock(&hdd_context_lock);
3479 if (context->request_id == pData->requestId) {
3480 context->response_status = pData->status ? -EINVAL : 0;
3481 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303483 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303484
3485 /*
3486 * Store the Request ID for comparing with the requestID obtained
3487 * in other requests.HDD shall return a failure is the extscan_stop
3488 * request is issued with a different requestId as that of the
3489 * extscan_start request. Also, This requestId shall be used while
3490 * indicating the full scan results to the upper layers.
3491 * The requestId is stored with the assumption that the firmware
3492 * shall return the ext scan start request's requestId in ext scan
3493 * start response.
3494 */
3495 if (pData->status == 0)
3496 pMac->sme.extScanStartReqId = pData->requestId;
3497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303498 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500}
3501
3502
3503static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3504{
3505 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3506 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303507 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303508
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303509 ENTER();
3510
3511 if (wlan_hdd_validate_context(pHddCtx)){
3512 return;
3513 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303515 if (!pMsg)
3516 {
3517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 return;
3519 }
3520
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303521 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3522 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303524 context = &pHddCtx->ext_scan_context;
3525 spin_lock(&hdd_context_lock);
3526 if (context->request_id == pData->requestId) {
3527 context->response_status = pData->status ? -EINVAL : 0;
3528 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303530 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303532 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303533 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534}
3535
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3537 void *pMsg)
3538{
3539 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 tpSirEXTScanSetBssidHotListRspParams pData =
3541 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303542 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303543
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303544 ENTER();
3545
3546 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547 return;
3548 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 if (!pMsg)
3551 {
3552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3553 return;
3554 }
3555
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303556 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3557 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303559 context = &pHddCtx->ext_scan_context;
3560 spin_lock(&hdd_context_lock);
3561 if (context->request_id == pData->requestId) {
3562 context->response_status = pData->status ? -EINVAL : 0;
3563 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303565 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303567 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303569}
3570
3571static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3572 void *pMsg)
3573{
3574 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303575 tpSirEXTScanResetBssidHotlistRspParams pData =
3576 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303577 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303579 ENTER();
3580
3581 if (wlan_hdd_validate_context(pHddCtx)) {
3582 return;
3583 }
3584 if (!pMsg)
3585 {
3586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 return;
3588 }
3589
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303590 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3591 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303593 context = &pHddCtx->ext_scan_context;
3594 spin_lock(&hdd_context_lock);
3595 if (context->request_id == pData->requestId) {
3596 context->response_status = pData->status ? -EINVAL : 0;
3597 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303599 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303601 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603}
3604
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3606 void *pMsg)
3607{
3608 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3609 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303610 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 tANI_S32 totalResults;
3612 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303613 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3614 struct hdd_ext_scan_context *context;
3615 bool ignore_cached_results = false;
3616 tExtscanCachedScanResult *result;
3617 struct nlattr *nla_results;
3618 tANI_U16 ieLength= 0;
3619 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303621 ENTER();
3622
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303623 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303624 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303625
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303626 if (!pMsg)
3627 {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3629 return;
3630 }
3631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 spin_lock(&hdd_context_lock);
3633 context = &pHddCtx->ext_scan_context;
3634 ignore_cached_results = context->ignore_cached_results;
3635 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303637 if (ignore_cached_results) {
3638 hddLog(LOGE,
3639 FL("Ignore the cached results received after timeout"));
3640 return;
3641 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303643 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3644 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303647
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303648 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3649 scan_id_index++) {
3650 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303652 totalResults = result->num_results;
3653 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3654 result->scan_id, result->flags, totalResults);
3655 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303656
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303657 do{
3658 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3659 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3660 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303662 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3663 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3664
3665 if (!skb) {
3666 hddLog(VOS_TRACE_LEVEL_ERROR,
3667 FL("cfg80211_vendor_event_alloc failed"));
3668 return;
3669 }
3670
3671 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3672
3673 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3674 pData->requestId) ||
3675 nla_put_u32(skb,
3676 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3677 resultsPerEvent)) {
3678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3679 goto fail;
3680 }
3681 if (nla_put_u8(skb,
3682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3683 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684 {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3686 goto fail;
3687 }
3688
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303689 if (nla_put_u32(skb,
3690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3691 result->scan_id)) {
3692 hddLog(LOGE, FL("put fail"));
3693 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303694 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303696 nla_results = nla_nest_start(skb,
3697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3698 if (!nla_results)
3699 goto fail;
3700
3701 if (resultsPerEvent) {
3702 struct nlattr *aps;
3703 struct nlattr *nla_result;
3704
3705 nla_result = nla_nest_start(skb, scan_id_index);
3706 if(!nla_result)
3707 goto fail;
3708
3709 if (nla_put_u32(skb,
3710 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3711 result->scan_id) ||
3712 nla_put_u32(skb,
3713 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3714 result->flags) ||
3715 nla_put_u32(skb,
3716 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3717 totalResults)) {
3718 hddLog(LOGE, FL("put fail"));
3719 goto fail;
3720 }
3721
3722 aps = nla_nest_start(skb,
3723 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3724 if (!aps)
3725 {
3726 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3727 goto fail;
3728 }
3729
3730 head_ptr = (tpSirWifiScanResult) &(result->ap);
3731
3732 for (j = 0; j < resultsPerEvent; j++, i++) {
3733 struct nlattr *ap;
3734 pSirWifiScanResult = head_ptr + i;
3735
3736 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303737 * Firmware returns timestamp from extscan_start till
3738 * BSSID was cached (in micro seconds). Add this with
3739 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303740 * to derive the time since boot when the
3741 * BSSID was cached.
3742 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303743 pSirWifiScanResult->ts +=
3744 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303745 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3746 "Ssid (%s)"
3747 "Bssid: %pM "
3748 "Channel (%u)"
3749 "Rssi (%d)"
3750 "RTT (%u)"
3751 "RTT_SD (%u)"
3752 "Beacon Period %u"
3753 "Capability 0x%x "
3754 "Ie length %d",
3755 i,
3756 pSirWifiScanResult->ts,
3757 pSirWifiScanResult->ssid,
3758 pSirWifiScanResult->bssid,
3759 pSirWifiScanResult->channel,
3760 pSirWifiScanResult->rssi,
3761 pSirWifiScanResult->rtt,
3762 pSirWifiScanResult->rtt_sd,
3763 pSirWifiScanResult->beaconPeriod,
3764 pSirWifiScanResult->capability,
3765 ieLength);
3766
3767 ap = nla_nest_start(skb, j + 1);
3768 if (!ap)
3769 {
3770 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3771 goto fail;
3772 }
3773
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303774 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303775 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3776 pSirWifiScanResult->ts) )
3777 {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3779 goto fail;
3780 }
3781 if (nla_put(skb,
3782 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3783 sizeof(pSirWifiScanResult->ssid),
3784 pSirWifiScanResult->ssid) )
3785 {
3786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3787 goto fail;
3788 }
3789 if (nla_put(skb,
3790 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3791 sizeof(pSirWifiScanResult->bssid),
3792 pSirWifiScanResult->bssid) )
3793 {
3794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3795 goto fail;
3796 }
3797 if (nla_put_u32(skb,
3798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3799 pSirWifiScanResult->channel) )
3800 {
3801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3802 goto fail;
3803 }
3804 if (nla_put_s32(skb,
3805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3806 pSirWifiScanResult->rssi) )
3807 {
3808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3809 goto fail;
3810 }
3811 if (nla_put_u32(skb,
3812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3813 pSirWifiScanResult->rtt) )
3814 {
3815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3816 goto fail;
3817 }
3818 if (nla_put_u32(skb,
3819 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3820 pSirWifiScanResult->rtt_sd))
3821 {
3822 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3823 goto fail;
3824 }
3825 if (nla_put_u32(skb,
3826 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3827 pSirWifiScanResult->beaconPeriod))
3828 {
3829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3830 goto fail;
3831 }
3832 if (nla_put_u32(skb,
3833 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3834 pSirWifiScanResult->capability))
3835 {
3836 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3837 goto fail;
3838 }
3839 if (nla_put_u32(skb,
3840 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3841 ieLength))
3842 {
3843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3844 goto fail;
3845 }
3846
3847 if (ieLength)
3848 if (nla_put(skb,
3849 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3850 ieLength, ie)) {
3851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3852 goto fail;
3853 }
3854
3855 nla_nest_end(skb, ap);
3856 }
3857 nla_nest_end(skb, aps);
3858 nla_nest_end(skb, nla_result);
3859 }
3860
3861 nla_nest_end(skb, nla_results);
3862
3863 cfg80211_vendor_cmd_reply(skb);
3864
3865 } while (totalResults > 0);
3866 }
3867
3868 if (!pData->moreData) {
3869 spin_lock(&hdd_context_lock);
3870 context->response_status = 0;
3871 complete(&context->response_event);
3872 spin_unlock(&hdd_context_lock);
3873 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303875 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303876 return;
3877fail:
3878 kfree_skb(skb);
3879 return;
3880}
3881
3882static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3883 void *pMsg)
3884{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303885 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303886 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3887 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303888 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303890 ENTER();
3891
3892 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303893 hddLog(LOGE,
3894 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303895 return;
3896 }
3897 if (!pMsg)
3898 {
3899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900 return;
3901 }
3902
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303903 if (pData->bss_found)
3904 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3905 else
3906 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3907
Dino Mycle6fb96c12014-06-10 11:52:40 +05303908 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3910 NULL,
3911#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303913 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303914
3915 if (!skb) {
3916 hddLog(VOS_TRACE_LEVEL_ERROR,
3917 FL("cfg80211_vendor_event_alloc failed"));
3918 return;
3919 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303920
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303921 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3922 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3923 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3924 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3925
3926 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303927 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3928 "Ssid (%s) "
3929 "Bssid (" MAC_ADDRESS_STR ") "
3930 "Channel (%u) "
3931 "Rssi (%d) "
3932 "RTT (%u) "
3933 "RTT_SD (%u) ",
3934 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303935 pData->bssHotlist[i].ts,
3936 pData->bssHotlist[i].ssid,
3937 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3938 pData->bssHotlist[i].channel,
3939 pData->bssHotlist[i].rssi,
3940 pData->bssHotlist[i].rtt,
3941 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 }
3943
3944 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3945 pData->requestId) ||
3946 nla_put_u32(skb,
3947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303948 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3950 goto fail;
3951 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303952 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303953 struct nlattr *aps;
3954
3955 aps = nla_nest_start(skb,
3956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3957 if (!aps)
3958 goto fail;
3959
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303960 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303961 struct nlattr *ap;
3962
3963 ap = nla_nest_start(skb, i + 1);
3964 if (!ap)
3965 goto fail;
3966
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303967 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 nla_put(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303972 sizeof(pData->bssHotlist[i].ssid),
3973 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303974 nla_put(skb,
3975 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303976 sizeof(pData->bssHotlist[i].bssid),
3977 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303978 nla_put_u32(skb,
3979 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303980 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303981 nla_put_s32(skb,
3982 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303983 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303984 nla_put_u32(skb,
3985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303986 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303987 nla_put_u32(skb,
3988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303989 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303990 goto fail;
3991
3992 nla_nest_end(skb, ap);
3993 }
3994 nla_nest_end(skb, aps);
3995
3996 if (nla_put_u8(skb,
3997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3998 pData->moreData))
3999 goto fail;
4000 }
4001
4002 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304003 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304004 return;
4005
4006fail:
4007 kfree_skb(skb);
4008 return;
4009
4010}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304011
4012static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4013 void *pMsg)
4014{
4015 struct sk_buff *skb;
4016 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4017 tpSirWifiFullScanResultEvent pData =
4018 (tpSirWifiFullScanResultEvent) (pMsg);
4019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304020 ENTER();
4021
4022 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304023 hddLog(LOGE,
4024 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304025 return;
4026 }
4027 if (!pMsg)
4028 {
4029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304030 return;
4031 }
4032
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304033 /*
4034 * If the full scan result including IE data exceeds NL 4K size
4035 * limitation, drop that beacon/probe rsp frame.
4036 */
4037 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4038 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4039 return;
4040 }
4041
Dino Mycle6fb96c12014-06-10 11:52:40 +05304042 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4044 NULL,
4045#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304046 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4047 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4048 GFP_KERNEL);
4049
4050 if (!skb) {
4051 hddLog(VOS_TRACE_LEVEL_ERROR,
4052 FL("cfg80211_vendor_event_alloc failed"));
4053 return;
4054 }
4055
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4057 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4059 "Ssid (%s)"
4060 "Bssid (" MAC_ADDRESS_STR ")"
4061 "Channel (%u)"
4062 "Rssi (%d)"
4063 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304064 "RTT_SD (%u)"
4065 "Bcn Period %d"
4066 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304067 pData->ap.ts,
4068 pData->ap.ssid,
4069 MAC_ADDR_ARRAY(pData->ap.bssid),
4070 pData->ap.channel,
4071 pData->ap.rssi,
4072 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304073 pData->ap.rtt_sd,
4074 pData->ap.beaconPeriod,
4075 pData->ap.capability);
4076
Dino Mycle6fb96c12014-06-10 11:52:40 +05304077 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4078 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4079 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304080 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304081 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4082 pData->ap.ts) ||
4083 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4084 sizeof(pData->ap.ssid),
4085 pData->ap.ssid) ||
4086 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4087 WNI_CFG_BSSID_LEN,
4088 pData->ap.bssid) ||
4089 nla_put_u32(skb,
4090 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4091 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304092 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304093 pData->ap.rssi) ||
4094 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4095 pData->ap.rtt) ||
4096 nla_put_u32(skb,
4097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4098 pData->ap.rtt_sd) ||
4099 nla_put_u16(skb,
4100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4101 pData->ap.beaconPeriod) ||
4102 nla_put_u16(skb,
4103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4104 pData->ap.capability) ||
4105 nla_put_u32(skb,
4106 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304107 pData->ieLength) ||
4108 nla_put_u8(skb,
4109 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4110 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304111 {
4112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4113 goto nla_put_failure;
4114 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304115
4116 if (pData->ieLength) {
4117 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4118 pData->ieLength,
4119 pData->ie))
4120 {
4121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4122 goto nla_put_failure;
4123 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304124 }
4125
4126 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304127 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 return;
4129
4130nla_put_failure:
4131 kfree_skb(skb);
4132 return;
4133}
4134
4135static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4136 void *pMsg)
4137{
4138 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4139 struct sk_buff *skb = NULL;
4140 tpSirEXTScanResultsAvailableIndParams pData =
4141 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4142
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304143 ENTER();
4144
4145 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304146 hddLog(LOGE,
4147 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304148 return;
4149 }
4150 if (!pMsg)
4151 {
4152 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304153 return;
4154 }
4155
4156 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4158 NULL,
4159#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304160 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4161 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4162 GFP_KERNEL);
4163
4164 if (!skb) {
4165 hddLog(VOS_TRACE_LEVEL_ERROR,
4166 FL("cfg80211_vendor_event_alloc failed"));
4167 return;
4168 }
4169
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4171 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4172 pData->numResultsAvailable);
4173 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4174 pData->requestId) ||
4175 nla_put_u32(skb,
4176 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4177 pData->numResultsAvailable)) {
4178 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4179 goto nla_put_failure;
4180 }
4181
4182 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304183 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304184 return;
4185
4186nla_put_failure:
4187 kfree_skb(skb);
4188 return;
4189}
4190
4191static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4192{
4193 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4194 struct sk_buff *skb = NULL;
4195 tpSirEXTScanProgressIndParams pData =
4196 (tpSirEXTScanProgressIndParams) pMsg;
4197
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304198 ENTER();
4199
4200 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304201 hddLog(LOGE,
4202 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304203 return;
4204 }
4205 if (!pMsg)
4206 {
4207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304208 return;
4209 }
4210
4211 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304212#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4213 NULL,
4214#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4216 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4217 GFP_KERNEL);
4218
4219 if (!skb) {
4220 hddLog(VOS_TRACE_LEVEL_ERROR,
4221 FL("cfg80211_vendor_event_alloc failed"));
4222 return;
4223 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4226 pData->extScanEventType);
4227 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4228 pData->status);
4229
4230 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4231 pData->extScanEventType) ||
4232 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304233 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4234 pData->requestId) ||
4235 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304236 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4237 pData->status)) {
4238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4239 goto nla_put_failure;
4240 }
4241
4242 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304243 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304244 return;
4245
4246nla_put_failure:
4247 kfree_skb(skb);
4248 return;
4249}
4250
4251void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4252 void *pMsg)
4253{
4254 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304256 ENTER();
4257
Dino Mycle6fb96c12014-06-10 11:52:40 +05304258 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 return;
4260 }
4261
4262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4263
4264
4265 switch(evType) {
4266 case SIR_HAL_EXTSCAN_START_RSP:
4267 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4268 break;
4269
4270 case SIR_HAL_EXTSCAN_STOP_RSP:
4271 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4272 break;
4273 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4274 /* There is no need to send this response to upper layer
4275 Just log the message */
4276 hddLog(VOS_TRACE_LEVEL_INFO,
4277 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4278 break;
4279 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4280 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4281 break;
4282
4283 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4284 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4285 break;
4286
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304288 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304289 break;
4290 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4291 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4292 break;
4293 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4294 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4295 break;
4296 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4297 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4298 break;
4299 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4300 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4301 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304302 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4303 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4304 break;
4305 default:
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4307 break;
4308 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304309 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304310}
4311
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304312static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4313 struct wireless_dev *wdev,
4314 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315{
Dino Myclee8843b32014-07-04 14:21:45 +05304316 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304317 struct net_device *dev = wdev->netdev;
4318 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4319 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4320 struct nlattr
4321 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4322 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304323 struct hdd_ext_scan_context *context;
4324 unsigned long rc;
4325 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304327 ENTER();
4328
Dino Mycle6fb96c12014-06-10 11:52:40 +05304329 status = wlan_hdd_validate_context(pHddCtx);
4330 if (0 != status)
4331 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304332 return -EINVAL;
4333 }
Dino Myclee8843b32014-07-04 14:21:45 +05304334 /* check the EXTScan Capability */
4335 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304336 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4337 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304338 {
4339 hddLog(VOS_TRACE_LEVEL_ERROR,
4340 FL("EXTScan not enabled/supported by Firmware"));
4341 return -EINVAL;
4342 }
4343
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4345 data, dataLen,
4346 wlan_hdd_extscan_config_policy)) {
4347 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4348 return -EINVAL;
4349 }
4350
4351 /* Parse and fetch request Id */
4352 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4354 return -EINVAL;
4355 }
4356
Dino Myclee8843b32014-07-04 14:21:45 +05304357 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304358 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360
Dino Myclee8843b32014-07-04 14:21:45 +05304361 reqMsg.sessionId = pAdapter->sessionId;
4362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304364 vos_spin_lock_acquire(&hdd_context_lock);
4365 context = &pHddCtx->ext_scan_context;
4366 context->request_id = reqMsg.requestId;
4367 INIT_COMPLETION(context->response_event);
4368 vos_spin_lock_release(&hdd_context_lock);
4369
Dino Myclee8843b32014-07-04 14:21:45 +05304370 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304371 if (!HAL_STATUS_SUCCESS(status)) {
4372 hddLog(VOS_TRACE_LEVEL_ERROR,
4373 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304374 return -EINVAL;
4375 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304376
4377 rc = wait_for_completion_timeout(&context->response_event,
4378 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4379 if (!rc) {
4380 hddLog(LOGE, FL("Target response timed out"));
4381 return -ETIMEDOUT;
4382 }
4383
4384 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4385 if (ret)
4386 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4387
4388 return ret;
4389
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304390 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304391 return 0;
4392}
4393
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304394static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4395 struct wireless_dev *wdev,
4396 const void *data, int dataLen)
4397{
4398 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304400 vos_ssr_protect(__func__);
4401 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4402 vos_ssr_unprotect(__func__);
4403
4404 return ret;
4405}
4406
4407static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4408 struct wireless_dev *wdev,
4409 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410{
Dino Myclee8843b32014-07-04 14:21:45 +05304411 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 struct net_device *dev = wdev->netdev;
4413 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4414 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4415 struct nlattr
4416 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4417 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304418 struct hdd_ext_scan_context *context;
4419 unsigned long rc;
4420 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304422 ENTER();
4423
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304424 if (VOS_FTM_MODE == hdd_get_conparam()) {
4425 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4426 return -EINVAL;
4427 }
4428
Dino Mycle6fb96c12014-06-10 11:52:40 +05304429 status = wlan_hdd_validate_context(pHddCtx);
4430 if (0 != status)
4431 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304432 return -EINVAL;
4433 }
Dino Myclee8843b32014-07-04 14:21:45 +05304434 /* check the EXTScan Capability */
4435 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304436 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4437 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304438 {
4439 hddLog(VOS_TRACE_LEVEL_ERROR,
4440 FL("EXTScan not enabled/supported by Firmware"));
4441 return -EINVAL;
4442 }
4443
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4445 data, dataLen,
4446 wlan_hdd_extscan_config_policy)) {
4447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4448 return -EINVAL;
4449 }
4450 /* Parse and fetch request Id */
4451 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4452 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4453 return -EINVAL;
4454 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304455
Dino Myclee8843b32014-07-04 14:21:45 +05304456 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304457 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4458
Dino Myclee8843b32014-07-04 14:21:45 +05304459 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304460
Dino Myclee8843b32014-07-04 14:21:45 +05304461 reqMsg.sessionId = pAdapter->sessionId;
4462 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304463
4464 /* Parse and fetch flush parameter */
4465 if (!tb
4466 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4467 {
4468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4469 goto failed;
4470 }
Dino Myclee8843b32014-07-04 14:21:45 +05304471 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304472 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4473
Dino Myclee8843b32014-07-04 14:21:45 +05304474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304475
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304476 spin_lock(&hdd_context_lock);
4477 context = &pHddCtx->ext_scan_context;
4478 context->request_id = reqMsg.requestId;
4479 context->ignore_cached_results = false;
4480 INIT_COMPLETION(context->response_event);
4481 spin_unlock(&hdd_context_lock);
4482
Dino Myclee8843b32014-07-04 14:21:45 +05304483 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304484 if (!HAL_STATUS_SUCCESS(status)) {
4485 hddLog(VOS_TRACE_LEVEL_ERROR,
4486 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304487 return -EINVAL;
4488 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304489
4490 rc = wait_for_completion_timeout(&context->response_event,
4491 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4492 if (!rc) {
4493 hddLog(LOGE, FL("Target response timed out"));
4494 retval = -ETIMEDOUT;
4495 spin_lock(&hdd_context_lock);
4496 context->ignore_cached_results = true;
4497 spin_unlock(&hdd_context_lock);
4498 } else {
4499 spin_lock(&hdd_context_lock);
4500 retval = context->response_status;
4501 spin_unlock(&hdd_context_lock);
4502 }
4503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304504 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304505 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506
4507failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304508 return -EINVAL;
4509}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304510static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4511 struct wireless_dev *wdev,
4512 const void *data, int dataLen)
4513{
4514 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304515
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304516 vos_ssr_protect(__func__);
4517 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4518 vos_ssr_unprotect(__func__);
4519
4520 return ret;
4521}
4522
4523static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304524 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304525 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304526{
4527 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4528 struct net_device *dev = wdev->netdev;
4529 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4531 struct nlattr
4532 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4533 struct nlattr
4534 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4535 struct nlattr *apTh;
4536 eHalStatus status;
4537 tANI_U8 i = 0;
4538 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304539 struct hdd_ext_scan_context *context;
4540 tANI_U32 request_id;
4541 unsigned long rc;
4542 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304543
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304544 ENTER();
4545
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304546 if (VOS_FTM_MODE == hdd_get_conparam()) {
4547 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4548 return -EINVAL;
4549 }
4550
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551 status = wlan_hdd_validate_context(pHddCtx);
4552 if (0 != status)
4553 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304554 return -EINVAL;
4555 }
Dino Myclee8843b32014-07-04 14:21:45 +05304556 /* check the EXTScan Capability */
4557 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304558 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4559 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304560 {
4561 hddLog(VOS_TRACE_LEVEL_ERROR,
4562 FL("EXTScan not enabled/supported by Firmware"));
4563 return -EINVAL;
4564 }
4565
Dino Mycle6fb96c12014-06-10 11:52:40 +05304566 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4567 data, dataLen,
4568 wlan_hdd_extscan_config_policy)) {
4569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4570 return -EINVAL;
4571 }
4572
4573 /* Parse and fetch request Id */
4574 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4576 return -EINVAL;
4577 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304578 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4579 vos_mem_malloc(sizeof(*pReqMsg));
4580 if (!pReqMsg) {
4581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4582 return -ENOMEM;
4583 }
4584
Dino Myclee8843b32014-07-04 14:21:45 +05304585
Dino Mycle6fb96c12014-06-10 11:52:40 +05304586 pReqMsg->requestId = nla_get_u32(
4587 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4589
4590 /* Parse and fetch number of APs */
4591 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4593 goto fail;
4594 }
4595
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304596 /* Parse and fetch lost ap sample size */
4597 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4598 hddLog(LOGE, FL("attr lost ap sample size failed"));
4599 goto fail;
4600 }
4601
4602 pReqMsg->lostBssidSampleSize = nla_get_u32(
4603 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4604 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4605
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606 pReqMsg->sessionId = pAdapter->sessionId;
4607 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4608
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304609 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304610 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304611 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4612 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4613 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4614 goto fail;
4615 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304616 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617
4618 nla_for_each_nested(apTh,
4619 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304620 if (i == pReqMsg->numBssid) {
4621 hddLog(LOGW, FL("Ignoring excess AP"));
4622 break;
4623 }
4624
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4626 nla_data(apTh), nla_len(apTh),
4627 NULL)) {
4628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4629 goto fail;
4630 }
4631
4632 /* Parse and fetch MAC address */
4633 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4635 goto fail;
4636 }
4637 memcpy(pReqMsg->ap[i].bssid, nla_data(
4638 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4639 sizeof(tSirMacAddr));
4640 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4641
4642 /* Parse and fetch low RSSI */
4643 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4645 goto fail;
4646 }
4647 pReqMsg->ap[i].low = nla_get_s32(
4648 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4649 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4650
4651 /* Parse and fetch high RSSI */
4652 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4654 goto fail;
4655 }
4656 pReqMsg->ap[i].high = nla_get_s32(
4657 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4658 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4659 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304660 i++;
4661 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304662
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304663 if (i < pReqMsg->numBssid) {
4664 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4665 i, pReqMsg->numBssid);
4666 pReqMsg->numBssid = i;
4667 }
4668
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304669 context = &pHddCtx->ext_scan_context;
4670 spin_lock(&hdd_context_lock);
4671 INIT_COMPLETION(context->response_event);
4672 context->request_id = request_id = pReqMsg->requestId;
4673 spin_unlock(&hdd_context_lock);
4674
Dino Mycle6fb96c12014-06-10 11:52:40 +05304675 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4676 if (!HAL_STATUS_SUCCESS(status)) {
4677 hddLog(VOS_TRACE_LEVEL_ERROR,
4678 FL("sme_SetBssHotlist failed(err=%d)"), status);
4679 vos_mem_free(pReqMsg);
4680 return -EINVAL;
4681 }
4682
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304683 /* request was sent -- wait for the response */
4684 rc = wait_for_completion_timeout(&context->response_event,
4685 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4686
4687 if (!rc) {
4688 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4689 retval = -ETIMEDOUT;
4690 } else {
4691 spin_lock(&hdd_context_lock);
4692 if (context->request_id == request_id)
4693 retval = context->response_status;
4694 else
4695 retval = -EINVAL;
4696 spin_unlock(&hdd_context_lock);
4697 }
4698
Dino Myclee8843b32014-07-04 14:21:45 +05304699 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304700 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304701 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304702
4703fail:
4704 vos_mem_free(pReqMsg);
4705 return -EINVAL;
4706}
4707
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304708static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4709 struct wireless_dev *wdev,
4710 const void *data, int dataLen)
4711{
4712 int ret = 0;
4713
4714 vos_ssr_protect(__func__);
4715 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4716 dataLen);
4717 vos_ssr_unprotect(__func__);
4718
4719 return ret;
4720}
4721
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304722static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304723 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304724 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304725{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304726 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4727 struct net_device *dev = wdev->netdev;
4728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4729 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4730 uint8_t num_channels = 0;
4731 uint8_t num_chan_new = 0;
4732 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304733 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304734 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 tWifiBand wifiBand;
4736 eHalStatus status;
4737 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304738 tANI_U8 i,j,k;
4739 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304741 ENTER();
4742
Dino Mycle6fb96c12014-06-10 11:52:40 +05304743 status = wlan_hdd_validate_context(pHddCtx);
4744 if (0 != status)
4745 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304746 return -EINVAL;
4747 }
Dino Myclee8843b32014-07-04 14:21:45 +05304748
Dino Mycle6fb96c12014-06-10 11:52:40 +05304749 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4750 data, dataLen,
4751 wlan_hdd_extscan_config_policy)) {
4752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4753 return -EINVAL;
4754 }
4755
4756 /* Parse and fetch request Id */
4757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4759 return -EINVAL;
4760 }
4761 requestId = nla_get_u32(
4762 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4763 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4764
4765 /* Parse and fetch wifi band */
4766 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4767 {
4768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4769 return -EINVAL;
4770 }
4771 wifiBand = nla_get_u32(
4772 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4773 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4774
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304775 /* Parse and fetch max channels */
4776 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4777 {
4778 hddLog(LOGE, FL("attr max channels failed"));
4779 return -EINVAL;
4780 }
4781 maxChannels = nla_get_u32(
4782 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4783 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4784
Dino Mycle6fb96c12014-06-10 11:52:40 +05304785 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304786 wifiBand, chan_list,
4787 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304788 if (eHAL_STATUS_SUCCESS != status) {
4789 hddLog(VOS_TRACE_LEVEL_ERROR,
4790 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4791 return -EINVAL;
4792 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304793
Agrawal Ashish16abf782016-08-18 22:42:59 +05304794 num_channels = VOS_MIN(num_channels, maxChannels);
4795 num_chan_new = num_channels;
4796 /* remove the indoor only channels if iface is SAP */
4797 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4798 {
4799 num_chan_new = 0;
4800 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304801 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304802 if (wiphy->bands[j] == NULL)
4803 continue;
4804 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4805 if ((chan_list[i] ==
4806 wiphy->bands[j]->channels[k].center_freq) &&
4807 (!(wiphy->bands[j]->channels[k].flags &
4808 IEEE80211_CHAN_INDOOR_ONLY))) {
4809 chan_list[num_chan_new] = chan_list[i];
4810 num_chan_new++;
4811 }
4812 }
4813 }
4814 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304815
Agrawal Ashish16abf782016-08-18 22:42:59 +05304816 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4817 for (i = 0; i < num_chan_new; i++)
4818 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4819 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304820
4821 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304822 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304823 NLMSG_HDRLEN);
4824
4825 if (!replySkb) {
4826 hddLog(VOS_TRACE_LEVEL_ERROR,
4827 FL("valid channels: buffer alloc fail"));
4828 return -EINVAL;
4829 }
4830 if (nla_put_u32(replySkb,
4831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304832 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304834 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304835
4836 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4837 kfree_skb(replySkb);
4838 return -EINVAL;
4839 }
4840
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304841 ret = cfg80211_vendor_cmd_reply(replySkb);
4842
4843 EXIT();
4844 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845}
4846
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304847static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4848 struct wireless_dev *wdev,
4849 const void *data, int dataLen)
4850{
4851 int ret = 0;
4852
4853 vos_ssr_protect(__func__);
4854 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4855 dataLen);
4856 vos_ssr_unprotect(__func__);
4857
4858 return ret;
4859}
4860
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304861static int hdd_extscan_start_fill_bucket_channel_spec(
4862 hdd_context_t *pHddCtx,
4863 tpSirEXTScanStartReqParams pReqMsg,
4864 struct nlattr **tb)
4865{
4866 struct nlattr *bucket[
4867 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4868 struct nlattr *channel[
4869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4870 struct nlattr *buckets;
4871 struct nlattr *channels;
4872 int rem1, rem2;
4873 eHalStatus status;
4874 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304875 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304876 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4877 tANI_U32 passive_max_chn_time, active_max_chn_time;
4878
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304879 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304880 bktIndex = 0;
4881
4882 nla_for_each_nested(buckets,
4883 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304884 if (bktIndex >= expected_buckets) {
4885 hddLog(LOGW, FL("ignoring excess buckets"));
4886 break;
4887 }
4888
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304889 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304890 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4891 nla_data(buckets), nla_len(buckets),
4892 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304893 hddLog(LOGE, FL("nla_parse failed"));
4894 return -EINVAL;
4895 }
4896
4897 /* Parse and fetch bucket spec */
4898 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4899 hddLog(LOGE, FL("attr bucket index failed"));
4900 return -EINVAL;
4901 }
4902 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4903 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4904 hddLog(LOG1, FL("Bucket spec Index %d"),
4905 pReqMsg->buckets[bktIndex].bucket);
4906
4907 /* Parse and fetch wifi band */
4908 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4909 hddLog(LOGE, FL("attr wifi band failed"));
4910 return -EINVAL;
4911 }
4912 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4913 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4914 hddLog(LOG1, FL("Wifi band %d"),
4915 pReqMsg->buckets[bktIndex].band);
4916
4917 /* Parse and fetch period */
4918 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4919 hddLog(LOGE, FL("attr period failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4923 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4924 hddLog(LOG1, FL("period %d"),
4925 pReqMsg->buckets[bktIndex].period);
4926
4927 /* Parse and fetch report events */
4928 if (!bucket[
4929 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4930 hddLog(LOGE, FL("attr report events failed"));
4931 return -EINVAL;
4932 }
4933 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4934 bucket[
4935 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4936 hddLog(LOG1, FL("report events %d"),
4937 pReqMsg->buckets[bktIndex].reportEvents);
4938
4939 /* Parse and fetch max period */
4940 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4941 hddLog(LOGE, FL("attr max period failed"));
4942 return -EINVAL;
4943 }
4944 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4945 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4946 hddLog(LOG1, FL("max period %u"),
4947 pReqMsg->buckets[bktIndex].max_period);
4948
4949 /* Parse and fetch exponent */
4950 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4951 hddLog(LOGE, FL("attr exponent failed"));
4952 return -EINVAL;
4953 }
4954 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4955 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4956 hddLog(LOG1, FL("exponent %u"),
4957 pReqMsg->buckets[bktIndex].exponent);
4958
4959 /* Parse and fetch step count */
4960 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4961 hddLog(LOGE, FL("attr step count failed"));
4962 return -EINVAL;
4963 }
4964 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4965 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4966 hddLog(LOG1, FL("Step count %u"),
4967 pReqMsg->buckets[bktIndex].step_count);
4968
4969 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4970 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4971
4972 /* Framework shall pass the channel list if the input WiFi band is
4973 * WIFI_BAND_UNSPECIFIED.
4974 * If the input WiFi band is specified (any value other than
4975 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4976 */
4977 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4978 numChannels = 0;
4979 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4980 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4981 pReqMsg->buckets[bktIndex].band,
4982 chanList, &numChannels);
4983 if (!HAL_STATUS_SUCCESS(status)) {
4984 hddLog(LOGE,
4985 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4986 status);
4987 return -EINVAL;
4988 }
4989
4990 pReqMsg->buckets[bktIndex].numChannels =
4991 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4992 hddLog(LOG1, FL("Num channels %d"),
4993 pReqMsg->buckets[bktIndex].numChannels);
4994
4995 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4996 j++) {
4997 pReqMsg->buckets[bktIndex].channels[j].channel =
4998 chanList[j];
4999 pReqMsg->buckets[bktIndex].channels[j].
5000 chnlClass = 0;
5001 if (CSR_IS_CHANNEL_DFS(
5002 vos_freq_to_chan(chanList[j]))) {
5003 pReqMsg->buckets[bktIndex].channels[j].
5004 passive = 1;
5005 pReqMsg->buckets[bktIndex].channels[j].
5006 dwellTimeMs = passive_max_chn_time;
5007 } else {
5008 pReqMsg->buckets[bktIndex].channels[j].
5009 passive = 0;
5010 pReqMsg->buckets[bktIndex].channels[j].
5011 dwellTimeMs = active_max_chn_time;
5012 }
5013
5014 hddLog(LOG1,
5015 "Channel %u Passive %u Dwell time %u ms",
5016 pReqMsg->buckets[bktIndex].channels[j].channel,
5017 pReqMsg->buckets[bktIndex].channels[j].passive,
5018 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5019 }
5020
5021 bktIndex++;
5022 continue;
5023 }
5024
5025 /* Parse and fetch number of channels */
5026 if (!bucket[
5027 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5028 hddLog(LOGE, FL("attr num channels failed"));
5029 return -EINVAL;
5030 }
5031
5032 pReqMsg->buckets[bktIndex].numChannels =
5033 nla_get_u32(bucket[
5034 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5035 hddLog(LOG1, FL("num channels %d"),
5036 pReqMsg->buckets[bktIndex].numChannels);
5037
5038 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5039 hddLog(LOGE, FL("attr channel spec failed"));
5040 return -EINVAL;
5041 }
5042
5043 j = 0;
5044 nla_for_each_nested(channels,
5045 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5046 if (nla_parse(channel,
5047 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5048 nla_data(channels), nla_len(channels),
5049 wlan_hdd_extscan_config_policy)) {
5050 hddLog(LOGE, FL("nla_parse failed"));
5051 return -EINVAL;
5052 }
5053
5054 /* Parse and fetch channel */
5055 if (!channel[
5056 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5057 hddLog(LOGE, FL("attr channel failed"));
5058 return -EINVAL;
5059 }
5060 pReqMsg->buckets[bktIndex].channels[j].channel =
5061 nla_get_u32(channel[
5062 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5063 hddLog(LOG1, FL("channel %u"),
5064 pReqMsg->buckets[bktIndex].channels[j].channel);
5065
5066 /* Parse and fetch dwell time */
5067 if (!channel[
5068 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5069 hddLog(LOGE, FL("attr dwelltime failed"));
5070 return -EINVAL;
5071 }
5072 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5073 nla_get_u32(channel[
5074 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5075
5076 hddLog(LOG1, FL("Dwell time (%u ms)"),
5077 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5078
5079
5080 /* Parse and fetch channel spec passive */
5081 if (!channel[
5082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5083 hddLog(LOGE,
5084 FL("attr channel spec passive failed"));
5085 return -EINVAL;
5086 }
5087 pReqMsg->buckets[bktIndex].channels[j].passive =
5088 nla_get_u8(channel[
5089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5090 hddLog(LOG1, FL("Chnl spec passive %u"),
5091 pReqMsg->buckets[bktIndex].channels[j].passive);
5092
5093 j++;
5094 }
5095
5096 bktIndex++;
5097 }
5098
5099 return 0;
5100}
5101
5102
5103/*
5104 * define short names for the global vendor params
5105 * used by wlan_hdd_cfg80211_extscan_start()
5106 */
5107#define PARAM_MAX \
5108QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5109#define PARAM_REQUEST_ID \
5110QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5111#define PARAM_BASE_PERIOD \
5112QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5113#define PARAM_MAX_AP_PER_SCAN \
5114QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5115#define PARAM_RPT_THRHLD_PERCENT \
5116QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5117#define PARAM_RPT_THRHLD_NUM_SCANS \
5118QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5119#define PARAM_NUM_BUCKETS \
5120QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305122static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305123 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305124 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125{
Dino Myclee8843b32014-07-04 14:21:45 +05305126 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305127 struct net_device *dev = wdev->netdev;
5128 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5129 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5130 struct nlattr *tb[PARAM_MAX + 1];
5131 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305132 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305133 tANI_U32 request_id;
5134 struct hdd_ext_scan_context *context;
5135 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305137 ENTER();
5138
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305139 if (VOS_FTM_MODE == hdd_get_conparam()) {
5140 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5141 return -EINVAL;
5142 }
5143
Dino Mycle6fb96c12014-06-10 11:52:40 +05305144 status = wlan_hdd_validate_context(pHddCtx);
5145 if (0 != status)
5146 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305147 return -EINVAL;
5148 }
Dino Myclee8843b32014-07-04 14:21:45 +05305149 /* check the EXTScan Capability */
5150 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305151 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5152 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305153 {
5154 hddLog(VOS_TRACE_LEVEL_ERROR,
5155 FL("EXTScan not enabled/supported by Firmware"));
5156 return -EINVAL;
5157 }
5158
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305159 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305160 data, dataLen,
5161 wlan_hdd_extscan_config_policy)) {
5162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5163 return -EINVAL;
5164 }
5165
5166 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305167 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305168 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5169 return -EINVAL;
5170 }
5171
Dino Myclee8843b32014-07-04 14:21:45 +05305172 pReqMsg = (tpSirEXTScanStartReqParams)
5173 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5176 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305177 }
5178
5179 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305180 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305181 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5182
5183 pReqMsg->sessionId = pAdapter->sessionId;
5184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5185
5186 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305187 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5189 goto fail;
5190 }
5191 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305192 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305193 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5194 pReqMsg->basePeriod);
5195
5196 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305197 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5199 goto fail;
5200 }
5201 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305202 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305203 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5204 pReqMsg->maxAPperScan);
5205
5206 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305207 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5209 goto fail;
5210 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305211 pReqMsg->reportThresholdPercent = nla_get_u8(
5212 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305214 pReqMsg->reportThresholdPercent);
5215
5216 /* Parse and fetch report threshold num scans */
5217 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5218 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5219 goto fail;
5220 }
5221 pReqMsg->reportThresholdNumScans = nla_get_u8(
5222 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5223 hddLog(LOG1, FL("Report Threshold num scans %d"),
5224 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305225
5226 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305227 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5229 goto fail;
5230 }
5231 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305232 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5234 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5235 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5236 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5237 }
5238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5239 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240
Dino Mycle6fb96c12014-06-10 11:52:40 +05305241 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5243 goto fail;
5244 }
5245
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305246 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305247
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305248 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5249 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305250
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305251 context = &pHddCtx->ext_scan_context;
5252 spin_lock(&hdd_context_lock);
5253 INIT_COMPLETION(context->response_event);
5254 context->request_id = request_id = pReqMsg->requestId;
5255 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305256
Dino Mycle6fb96c12014-06-10 11:52:40 +05305257 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5258 if (!HAL_STATUS_SUCCESS(status)) {
5259 hddLog(VOS_TRACE_LEVEL_ERROR,
5260 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305261 goto fail;
5262 }
5263
Srinivas Dasari91727c12016-03-23 17:59:06 +05305264 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5265
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305266 /* request was sent -- wait for the response */
5267 rc = wait_for_completion_timeout(&context->response_event,
5268 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5269
5270 if (!rc) {
5271 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5272 retval = -ETIMEDOUT;
5273 } else {
5274 spin_lock(&hdd_context_lock);
5275 if (context->request_id == request_id)
5276 retval = context->response_status;
5277 else
5278 retval = -EINVAL;
5279 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305280 }
5281
Dino Myclee8843b32014-07-04 14:21:45 +05305282 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305283 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305284 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305285
5286fail:
5287 vos_mem_free(pReqMsg);
5288 return -EINVAL;
5289}
5290
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305291/*
5292 * done with short names for the global vendor params
5293 * used by wlan_hdd_cfg80211_extscan_start()
5294 */
5295#undef PARAM_MAX
5296#undef PARAM_REQUEST_ID
5297#undef PARAM_BASE_PERIOD
5298#undef PARAMS_MAX_AP_PER_SCAN
5299#undef PARAMS_RPT_THRHLD_PERCENT
5300#undef PARAMS_RPT_THRHLD_NUM_SCANS
5301#undef PARAMS_NUM_BUCKETS
5302
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305303static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5304 struct wireless_dev *wdev,
5305 const void *data, int dataLen)
5306{
5307 int ret = 0;
5308
5309 vos_ssr_protect(__func__);
5310 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5311 vos_ssr_unprotect(__func__);
5312
5313 return ret;
5314}
5315
5316static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305317 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305318 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319{
Dino Myclee8843b32014-07-04 14:21:45 +05305320 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305321 struct net_device *dev = wdev->netdev;
5322 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5323 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5324 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5325 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305326 int retval;
5327 unsigned long rc;
5328 struct hdd_ext_scan_context *context;
5329 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305330
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305331 ENTER();
5332
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305333 if (VOS_FTM_MODE == hdd_get_conparam()) {
5334 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5335 return -EINVAL;
5336 }
5337
Dino Mycle6fb96c12014-06-10 11:52:40 +05305338 status = wlan_hdd_validate_context(pHddCtx);
5339 if (0 != status)
5340 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305341 return -EINVAL;
5342 }
Dino Myclee8843b32014-07-04 14:21:45 +05305343 /* check the EXTScan Capability */
5344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5346 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305347 {
5348 hddLog(VOS_TRACE_LEVEL_ERROR,
5349 FL("EXTScan not enabled/supported by Firmware"));
5350 return -EINVAL;
5351 }
5352
Dino Mycle6fb96c12014-06-10 11:52:40 +05305353 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5354 data, dataLen,
5355 wlan_hdd_extscan_config_policy)) {
5356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5357 return -EINVAL;
5358 }
5359
5360 /* Parse and fetch request Id */
5361 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5363 return -EINVAL;
5364 }
5365
Dino Myclee8843b32014-07-04 14:21:45 +05305366 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305368 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369
Dino Myclee8843b32014-07-04 14:21:45 +05305370 reqMsg.sessionId = pAdapter->sessionId;
5371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305373 context = &pHddCtx->ext_scan_context;
5374 spin_lock(&hdd_context_lock);
5375 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305376 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305377 spin_unlock(&hdd_context_lock);
5378
Dino Myclee8843b32014-07-04 14:21:45 +05305379 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305380 if (!HAL_STATUS_SUCCESS(status)) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR,
5382 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305383 return -EINVAL;
5384 }
5385
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305386 /* request was sent -- wait for the response */
5387 rc = wait_for_completion_timeout(&context->response_event,
5388 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5389
5390 if (!rc) {
5391 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5392 retval = -ETIMEDOUT;
5393 } else {
5394 spin_lock(&hdd_context_lock);
5395 if (context->request_id == request_id)
5396 retval = context->response_status;
5397 else
5398 retval = -EINVAL;
5399 spin_unlock(&hdd_context_lock);
5400 }
5401
5402 return retval;
5403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305404 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305405 return 0;
5406}
5407
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305408static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5409 struct wireless_dev *wdev,
5410 const void *data, int dataLen)
5411{
5412 int ret = 0;
5413
5414 vos_ssr_protect(__func__);
5415 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5416 vos_ssr_unprotect(__func__);
5417
5418 return ret;
5419}
5420
5421static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305422 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305423 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424{
Dino Myclee8843b32014-07-04 14:21:45 +05305425 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305426 struct net_device *dev = wdev->netdev;
5427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5428 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5429 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5430 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305431 struct hdd_ext_scan_context *context;
5432 tANI_U32 request_id;
5433 unsigned long rc;
5434 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305435
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305436 ENTER();
5437
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305438 if (VOS_FTM_MODE == hdd_get_conparam()) {
5439 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5440 return -EINVAL;
5441 }
5442
Dino Mycle6fb96c12014-06-10 11:52:40 +05305443 status = wlan_hdd_validate_context(pHddCtx);
5444 if (0 != status)
5445 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305446 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305447 return -EINVAL;
5448 }
Dino Myclee8843b32014-07-04 14:21:45 +05305449 /* check the EXTScan Capability */
5450 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305451 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5452 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305453 {
5454 hddLog(VOS_TRACE_LEVEL_ERROR,
5455 FL("EXTScan not enabled/supported by Firmware"));
5456 return -EINVAL;
5457 }
5458
Dino Mycle6fb96c12014-06-10 11:52:40 +05305459 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5460 data, dataLen,
5461 wlan_hdd_extscan_config_policy)) {
5462 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5463 return -EINVAL;
5464 }
5465
5466 /* Parse and fetch request Id */
5467 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5469 return -EINVAL;
5470 }
5471
Dino Myclee8843b32014-07-04 14:21:45 +05305472 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305473 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305475
Dino Myclee8843b32014-07-04 14:21:45 +05305476 reqMsg.sessionId = pAdapter->sessionId;
5477 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305479 context = &pHddCtx->ext_scan_context;
5480 spin_lock(&hdd_context_lock);
5481 INIT_COMPLETION(context->response_event);
5482 context->request_id = request_id = reqMsg.requestId;
5483 spin_unlock(&hdd_context_lock);
5484
Dino Myclee8843b32014-07-04 14:21:45 +05305485 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305486 if (!HAL_STATUS_SUCCESS(status)) {
5487 hddLog(VOS_TRACE_LEVEL_ERROR,
5488 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305489 return -EINVAL;
5490 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305491
5492 /* request was sent -- wait for the response */
5493 rc = wait_for_completion_timeout(&context->response_event,
5494 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5495 if (!rc) {
5496 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5497 retval = -ETIMEDOUT;
5498 } else {
5499 spin_lock(&hdd_context_lock);
5500 if (context->request_id == request_id)
5501 retval = context->response_status;
5502 else
5503 retval = -EINVAL;
5504 spin_unlock(&hdd_context_lock);
5505 }
5506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305507 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305508 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305509}
5510
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305511static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5512 struct wireless_dev *wdev,
5513 const void *data, int dataLen)
5514{
5515 int ret = 0;
5516
5517 vos_ssr_protect(__func__);
5518 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5519 vos_ssr_unprotect(__func__);
5520
5521 return ret;
5522}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305523#endif /* WLAN_FEATURE_EXTSCAN */
5524
Atul Mittal115287b2014-07-08 13:26:33 +05305525/*EXT TDLS*/
5526static const struct nla_policy
5527wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5528{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305529 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5530 .type = NLA_UNSPEC,
5531 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305532 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5533 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5534 {.type = NLA_S32 },
5535 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5536 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5537
5538};
5539
5540static const struct nla_policy
5541wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5542{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305543 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5544 .type = NLA_UNSPEC,
5545 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305546
5547};
5548
5549static const struct nla_policy
5550wlan_hdd_tdls_config_state_change_policy[
5551 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5552{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305553 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5554 .type = NLA_UNSPEC,
5555 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305556 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5557 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305558 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5559 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5560 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305561
5562};
5563
5564static const struct nla_policy
5565wlan_hdd_tdls_config_get_status_policy[
5566 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5567{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305568 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5569 .type = NLA_UNSPEC,
5570 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305571 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5572 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305573 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5574 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5575 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305576
5577};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305578
5579static const struct nla_policy
5580wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5581{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305582 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5583 .type = NLA_UNSPEC,
5584 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305585};
5586
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305587static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305589 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305590 int data_len)
5591{
5592
5593 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5594 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305596 ENTER();
5597
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305598 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305599 return -EINVAL;
5600 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305601 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305602 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305603 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305604 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305605 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305606 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305607 return -ENOTSUPP;
5608 }
5609
5610 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5611 data, data_len, wlan_hdd_mac_config)) {
5612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5613 return -EINVAL;
5614 }
5615
5616 /* Parse and fetch mac address */
5617 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5619 return -EINVAL;
5620 }
5621
5622 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5623 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5624 VOS_MAC_ADDR_LAST_3_BYTES);
5625
Siddharth Bhal76972212014-10-15 16:22:51 +05305626 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5627
5628 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305629 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5630 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305631 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5632 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5633 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5634 {
5635 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5636 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5637 VOS_MAC_ADDRESS_LEN);
5638 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305639 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305640
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305641 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5642 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305643
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305644 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305645 return 0;
5646}
5647
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305648static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5649 struct wireless_dev *wdev,
5650 const void *data,
5651 int data_len)
5652{
5653 int ret = 0;
5654
5655 vos_ssr_protect(__func__);
5656 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5657 vos_ssr_unprotect(__func__);
5658
5659 return ret;
5660}
5661
5662static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305663 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305664 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305665 int data_len)
5666{
5667 u8 peer[6] = {0};
5668 struct net_device *dev = wdev->netdev;
5669 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5670 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5671 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5672 eHalStatus ret;
5673 tANI_S32 state;
5674 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305675 tANI_S32 global_operating_class = 0;
5676 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305677 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305678 int retVal;
5679
5680 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305681
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305682 if (!pAdapter) {
5683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5684 return -EINVAL;
5685 }
5686
Atul Mittal115287b2014-07-08 13:26:33 +05305687 ret = wlan_hdd_validate_context(pHddCtx);
5688 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305689 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305690 return -EINVAL;
5691 }
5692 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305694 return -ENOTSUPP;
5695 }
5696 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5697 data, data_len,
5698 wlan_hdd_tdls_config_get_status_policy)) {
5699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5700 return -EINVAL;
5701 }
5702
5703 /* Parse and fetch mac address */
5704 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5705 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5706 return -EINVAL;
5707 }
5708
5709 memcpy(peer, nla_data(
5710 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5711 sizeof(peer));
5712 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5713
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305714 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305715
Atul Mittal115287b2014-07-08 13:26:33 +05305716 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305717 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305718 NLMSG_HDRLEN);
5719
5720 if (!skb) {
5721 hddLog(VOS_TRACE_LEVEL_ERROR,
5722 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5723 return -EINVAL;
5724 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305725 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 +05305726 reason,
5727 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305728 global_operating_class,
5729 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305730 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305731 if (nla_put_s32(skb,
5732 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5733 state) ||
5734 nla_put_s32(skb,
5735 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5736 reason) ||
5737 nla_put_s32(skb,
5738 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5739 global_operating_class) ||
5740 nla_put_s32(skb,
5741 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5742 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305743
5744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5745 goto nla_put_failure;
5746 }
5747
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305748 retVal = cfg80211_vendor_cmd_reply(skb);
5749 EXIT();
5750 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305751
5752nla_put_failure:
5753 kfree_skb(skb);
5754 return -EINVAL;
5755}
5756
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305757static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5758 struct wireless_dev *wdev,
5759 const void *data,
5760 int data_len)
5761{
5762 int ret = 0;
5763
5764 vos_ssr_protect(__func__);
5765 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5766 vos_ssr_unprotect(__func__);
5767
5768 return ret;
5769}
5770
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305771static int wlan_hdd_cfg80211_exttdls_callback(
5772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5773 const tANI_U8* mac,
5774#else
5775 tANI_U8* mac,
5776#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305777 tANI_S32 state,
5778 tANI_S32 reason,
5779 void *ctx)
5780{
5781 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305782 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305783 tANI_S32 global_operating_class = 0;
5784 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305785 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305786
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305787 ENTER();
5788
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305789 if (!pAdapter) {
5790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5791 return -EINVAL;
5792 }
5793
5794 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305795 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305797 return -EINVAL;
5798 }
5799
5800 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305802 return -ENOTSUPP;
5803 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305804 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5806 NULL,
5807#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305808 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5809 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5810 GFP_KERNEL);
5811
5812 if (!skb) {
5813 hddLog(VOS_TRACE_LEVEL_ERROR,
5814 FL("cfg80211_vendor_event_alloc failed"));
5815 return -EINVAL;
5816 }
5817 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305818 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5819 reason,
5820 state,
5821 global_operating_class,
5822 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305823 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5824 MAC_ADDR_ARRAY(mac));
5825
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305826 if (nla_put(skb,
5827 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5828 VOS_MAC_ADDR_SIZE, mac) ||
5829 nla_put_s32(skb,
5830 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5831 state) ||
5832 nla_put_s32(skb,
5833 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5834 reason) ||
5835 nla_put_s32(skb,
5836 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5837 channel) ||
5838 nla_put_s32(skb,
5839 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5840 global_operating_class)
5841 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5843 goto nla_put_failure;
5844 }
5845
5846 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305847 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305848 return (0);
5849
5850nla_put_failure:
5851 kfree_skb(skb);
5852 return -EINVAL;
5853}
5854
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305855static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305856 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305857 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305858 int data_len)
5859{
5860 u8 peer[6] = {0};
5861 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305862 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5863 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5864 eHalStatus status;
5865 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305866 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305867 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305868
5869 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305870
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305871 if (!dev) {
5872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5873 return -EINVAL;
5874 }
5875
5876 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5877 if (!pAdapter) {
5878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5879 return -EINVAL;
5880 }
5881
Atul Mittal115287b2014-07-08 13:26:33 +05305882 status = wlan_hdd_validate_context(pHddCtx);
5883 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305884 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305885 return -EINVAL;
5886 }
5887 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305889 return -ENOTSUPP;
5890 }
5891 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5892 data, data_len,
5893 wlan_hdd_tdls_config_enable_policy)) {
5894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5895 return -EINVAL;
5896 }
5897
5898 /* Parse and fetch mac address */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5901 return -EINVAL;
5902 }
5903
5904 memcpy(peer, nla_data(
5905 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5906 sizeof(peer));
5907 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5908
5909 /* Parse and fetch channel */
5910 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5911 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5912 return -EINVAL;
5913 }
5914 pReqMsg.channel = nla_get_s32(
5915 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5916 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5917
5918 /* Parse and fetch global operating class */
5919 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5920 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5921 return -EINVAL;
5922 }
5923 pReqMsg.global_operating_class = nla_get_s32(
5924 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5925 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5926 pReqMsg.global_operating_class);
5927
5928 /* Parse and fetch latency ms */
5929 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5931 return -EINVAL;
5932 }
5933 pReqMsg.max_latency_ms = nla_get_s32(
5934 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5936 pReqMsg.max_latency_ms);
5937
5938 /* Parse and fetch required bandwidth kbps */
5939 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5941 return -EINVAL;
5942 }
5943
5944 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5945 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5947 pReqMsg.min_bandwidth_kbps);
5948
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305949 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305950 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305951 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305952 wlan_hdd_cfg80211_exttdls_callback);
5953
5954 EXIT();
5955 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305956}
5957
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305958static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5959 struct wireless_dev *wdev,
5960 const void *data,
5961 int data_len)
5962{
5963 int ret = 0;
5964
5965 vos_ssr_protect(__func__);
5966 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5967 vos_ssr_unprotect(__func__);
5968
5969 return ret;
5970}
5971
5972static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305973 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305974 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305975 int data_len)
5976{
5977 u8 peer[6] = {0};
5978 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305979 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5980 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5981 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305982 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305983 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305984
5985 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305986
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305987 if (!dev) {
5988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5989 return -EINVAL;
5990 }
5991
5992 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5993 if (!pAdapter) {
5994 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5995 return -EINVAL;
5996 }
5997
Atul Mittal115287b2014-07-08 13:26:33 +05305998 status = wlan_hdd_validate_context(pHddCtx);
5999 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05306001 return -EINVAL;
6002 }
6003 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05306005 return -ENOTSUPP;
6006 }
6007 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
6008 data, data_len,
6009 wlan_hdd_tdls_config_disable_policy)) {
6010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6011 return -EINVAL;
6012 }
6013 /* Parse and fetch mac address */
6014 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6016 return -EINVAL;
6017 }
6018
6019 memcpy(peer, nla_data(
6020 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6021 sizeof(peer));
6022 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6023
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306024 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6025
6026 EXIT();
6027 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306028}
6029
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306030static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6031 struct wireless_dev *wdev,
6032 const void *data,
6033 int data_len)
6034{
6035 int ret = 0;
6036
6037 vos_ssr_protect(__func__);
6038 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6039 vos_ssr_unprotect(__func__);
6040
6041 return ret;
6042}
6043
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306045__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306047 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306048{
6049 struct net_device *dev = wdev->netdev;
6050 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6051 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6052 struct sk_buff *skb = NULL;
6053 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306054 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306055
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306056 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306057
6058 ret = wlan_hdd_validate_context(pHddCtx);
6059 if (0 != ret)
6060 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306061 return ret;
6062 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306063 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6064 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6065 fset |= WIFI_FEATURE_INFRA;
6066 }
6067
6068 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6069 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6070 fset |= WIFI_FEATURE_INFRA_5G;
6071 }
6072
6073#ifdef WLAN_FEATURE_P2P
6074 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6075 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6076 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6077 fset |= WIFI_FEATURE_P2P;
6078 }
6079#endif
6080
6081 /* Soft-AP is supported currently by default */
6082 fset |= WIFI_FEATURE_SOFT_AP;
6083
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306084 /* HOTSPOT is a supplicant feature, enable it by default */
6085 fset |= WIFI_FEATURE_HOTSPOT;
6086
Dasari Srinivas7875a302014-09-26 17:50:57 +05306087#ifdef WLAN_FEATURE_EXTSCAN
6088 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306089 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6090 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6091 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306092 fset |= WIFI_FEATURE_EXTSCAN;
6093 }
6094#endif
6095
Dasari Srinivas7875a302014-09-26 17:50:57 +05306096 if (sme_IsFeatureSupportedByFW(NAN)) {
6097 hddLog(LOG1, FL("NAN is supported by firmware"));
6098 fset |= WIFI_FEATURE_NAN;
6099 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306100
6101 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306102 if (sme_IsFeatureSupportedByFW(RTT) &&
6103 pHddCtx->cfg_ini->enable_rtt_support) {
6104 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306105 fset |= WIFI_FEATURE_D2AP_RTT;
6106 }
6107
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306108 if (sme_IsFeatureSupportedByFW(RTT3)) {
6109 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6110 fset |= WIFI_FEATURE_RTT3;
6111 }
6112
Dasari Srinivas7875a302014-09-26 17:50:57 +05306113#ifdef FEATURE_WLAN_BATCH_SCAN
6114 if (fset & WIFI_FEATURE_EXTSCAN) {
6115 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6116 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6117 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6118 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6119 fset |= WIFI_FEATURE_BATCH_SCAN;
6120 }
6121#endif
6122
6123#ifdef FEATURE_WLAN_SCAN_PNO
6124 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6125 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6126 hddLog(LOG1, FL("PNO is supported by firmware"));
6127 fset |= WIFI_FEATURE_PNO;
6128 }
6129#endif
6130
6131 /* STA+STA is supported currently by default */
6132 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6133
6134#ifdef FEATURE_WLAN_TDLS
6135 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6136 sme_IsFeatureSupportedByFW(TDLS)) {
6137 hddLog(LOG1, FL("TDLS is supported by firmware"));
6138 fset |= WIFI_FEATURE_TDLS;
6139 }
6140
6141 /* TDLS_OFFCHANNEL is not supported currently by default */
6142#endif
6143
6144#ifdef WLAN_AP_STA_CONCURRENCY
6145 /* AP+STA concurrency is supported currently by default */
6146 fset |= WIFI_FEATURE_AP_STA;
6147#endif
6148
Mukul Sharma5add0532015-08-17 15:57:47 +05306149#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306150 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6151 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306152 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6153 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306154 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306155#endif
6156
Dasari Srinivas7875a302014-09-26 17:50:57 +05306157 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6158 NLMSG_HDRLEN);
6159
6160 if (!skb) {
6161 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6162 return -EINVAL;
6163 }
6164 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6165
6166 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6167 hddLog(LOGE, FL("nla put fail"));
6168 goto nla_put_failure;
6169 }
6170
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306171 ret = cfg80211_vendor_cmd_reply(skb);
6172 EXIT();
6173 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306174
6175nla_put_failure:
6176 kfree_skb(skb);
6177 return -EINVAL;
6178}
6179
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306180static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306181wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6182 struct wireless_dev *wdev,
6183 const void *data, int data_len)
6184{
6185 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306186 vos_ssr_protect(__func__);
6187 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6188 vos_ssr_unprotect(__func__);
6189
6190 return ret;
6191}
6192
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306193
6194static const struct
6195nla_policy
6196qca_wlan_vendor_wifi_logger_get_ring_data_policy
6197[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6198 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6199 = {.type = NLA_U32 },
6200};
6201
6202static int
6203 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6204 struct wireless_dev *wdev,
6205 const void *data,
6206 int data_len)
6207{
6208 int ret;
6209 VOS_STATUS status;
6210 uint32_t ring_id;
6211 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6212 struct nlattr *tb
6213 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6214
6215 ENTER();
6216
6217 ret = wlan_hdd_validate_context(hdd_ctx);
6218 if (0 != ret) {
6219 return ret;
6220 }
6221
6222 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6223 data, data_len,
6224 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6225 hddLog(LOGE, FL("Invalid attribute"));
6226 return -EINVAL;
6227 }
6228
6229 /* Parse and fetch ring id */
6230 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6231 hddLog(LOGE, FL("attr ATTR failed"));
6232 return -EINVAL;
6233 }
6234
6235 ring_id = nla_get_u32(
6236 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6237
6238 hddLog(LOG1, FL("Bug report triggered by framework"));
6239
6240 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6241 WLAN_LOG_INDICATOR_FRAMEWORK,
6242 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306243 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306244 );
6245 if (VOS_STATUS_SUCCESS != status) {
6246 hddLog(LOGE, FL("Failed to trigger bug report"));
6247
6248 return -EINVAL;
6249 }
6250
6251 return 0;
6252
6253
6254}
6255
6256
6257static int
6258 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6259 struct wireless_dev *wdev,
6260 const void *data,
6261 int data_len)
6262{
6263 int ret = 0;
6264
6265 vos_ssr_protect(__func__);
6266 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6267 wdev, data, data_len);
6268 vos_ssr_unprotect(__func__);
6269
6270 return ret;
6271
6272}
6273
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306274#define MAX_CONCURRENT_MATRIX \
6275 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6276#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6277 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6278static const struct nla_policy
6279wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6280 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6281};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306282
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306283static int
6284__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306285 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306286 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306287{
6288 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6289 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306290 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306291 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306292 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6293 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294
6295 ENTER();
6296
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306297 ret = wlan_hdd_validate_context(pHddCtx);
6298 if (0 != ret)
6299 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306300 return ret;
6301 }
6302
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306303 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6304 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306305 hddLog(LOGE, FL("Invalid ATTR"));
6306 return -EINVAL;
6307 }
6308
6309 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306310 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306311 hddLog(LOGE, FL("Attr max feature set size failed"));
6312 return -EINVAL;
6313 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306314 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306315 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6316
6317 /* Fill feature combination matrix */
6318 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306319 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6320 WIFI_FEATURE_P2P;
6321
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306322 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6323 WIFI_FEATURE_SOFT_AP;
6324
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306325 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6326 WIFI_FEATURE_SOFT_AP;
6327
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306328 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6329 WIFI_FEATURE_SOFT_AP |
6330 WIFI_FEATURE_P2P;
6331
6332 /* Add more feature combinations here */
6333
6334 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6335 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6336 hddLog(LOG1, "Feature set matrix");
6337 for (i = 0; i < feature_sets; i++)
6338 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6339
6340 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6341 sizeof(u32) * feature_sets +
6342 NLMSG_HDRLEN);
6343
6344 if (reply_skb) {
6345 if (nla_put_u32(reply_skb,
6346 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6347 feature_sets) ||
6348 nla_put(reply_skb,
6349 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6350 sizeof(u32) * feature_sets, feature_set_matrix)) {
6351 hddLog(LOGE, FL("nla put fail"));
6352 kfree_skb(reply_skb);
6353 return -EINVAL;
6354 }
6355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306356 ret = cfg80211_vendor_cmd_reply(reply_skb);
6357 EXIT();
6358 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306359 }
6360 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6361 return -ENOMEM;
6362
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306363}
6364
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306365#undef MAX_CONCURRENT_MATRIX
6366#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6367
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306368static int
6369wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6370 struct wireless_dev *wdev,
6371 const void *data, int data_len)
6372{
6373 int ret = 0;
6374
6375 vos_ssr_protect(__func__);
6376 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6377 data_len);
6378 vos_ssr_unprotect(__func__);
6379
6380 return ret;
6381}
6382
c_manjeecfd1efb2015-09-25 19:32:34 +05306383
6384static int
6385__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6386 struct wireless_dev *wdev,
6387 const void *data, int data_len)
6388{
6389 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6390 int ret;
6391 ENTER();
6392
6393 ret = wlan_hdd_validate_context(pHddCtx);
6394 if (0 != ret)
6395 {
6396 return ret;
6397 }
6398
6399 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6400 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6401 {
6402 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306403 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306404 }
6405 /*call common API for FW mem dump req*/
6406 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6407
Abhishek Singhc783fa72015-12-09 18:07:34 +05306408 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306409 {
6410 /*indicate to userspace the status of fw mem dump */
6411 wlan_indicate_mem_dump_complete(true);
6412 }
6413 else
6414 {
6415 /*else send failure to userspace */
6416 wlan_indicate_mem_dump_complete(false);
6417 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306418 EXIT();
6419 return ret;
6420}
6421
6422/**
6423 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6424 * @wiphy: pointer to wireless wiphy structure.
6425 * @wdev: pointer to wireless_dev structure.
6426 * @data: Pointer to the NL data.
6427 * @data_len:Length of @data
6428 *
6429 * This is called when wlan driver needs to get the firmware memory dump
6430 * via vendor specific command.
6431 *
6432 * Return: 0 on success, error number otherwise.
6433 */
6434
6435static int
6436wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6437 struct wireless_dev *wdev,
6438 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306439{
6440 int ret = 0;
6441 vos_ssr_protect(__func__);
6442 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6443 data_len);
6444 vos_ssr_unprotect(__func__);
6445 return ret;
6446}
c_manjeecfd1efb2015-09-25 19:32:34 +05306447
Sushant Kaushik8e644982015-09-23 12:18:54 +05306448static const struct
6449nla_policy
6450qca_wlan_vendor_wifi_logger_start_policy
6451[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6452 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6453 = {.type = NLA_U32 },
6454 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6455 = {.type = NLA_U32 },
6456 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6457 = {.type = NLA_U32 },
6458};
6459
6460/**
6461 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6462 * or disable the collection of packet statistics from the firmware
6463 * @wiphy: WIPHY structure pointer
6464 * @wdev: Wireless device structure pointer
6465 * @data: Pointer to the data received
6466 * @data_len: Length of the data received
6467 *
6468 * This function is used to enable or disable the collection of packet
6469 * statistics from the firmware
6470 *
6471 * Return: 0 on success and errno on failure
6472 */
6473static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6474 struct wireless_dev *wdev,
6475 const void *data,
6476 int data_len)
6477{
6478 eHalStatus status;
6479 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6480 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6481 tAniWifiStartLog start_log;
6482
6483 status = wlan_hdd_validate_context(hdd_ctx);
6484 if (0 != status) {
6485 return -EINVAL;
6486 }
6487
6488 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6489 data, data_len,
6490 qca_wlan_vendor_wifi_logger_start_policy)) {
6491 hddLog(LOGE, FL("Invalid attribute"));
6492 return -EINVAL;
6493 }
6494
6495 /* Parse and fetch ring id */
6496 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6497 hddLog(LOGE, FL("attr ATTR failed"));
6498 return -EINVAL;
6499 }
6500 start_log.ringId = nla_get_u32(
6501 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6502 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6503
6504 /* Parse and fetch verbose level */
6505 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6506 hddLog(LOGE, FL("attr verbose_level failed"));
6507 return -EINVAL;
6508 }
6509 start_log.verboseLevel = nla_get_u32(
6510 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6511 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6512
6513 /* Parse and fetch flag */
6514 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6515 hddLog(LOGE, FL("attr flag failed"));
6516 return -EINVAL;
6517 }
6518 start_log.flag = nla_get_u32(
6519 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6520 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6521
6522 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306523 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6524 !vos_isPktStatsEnabled()))
6525
Sushant Kaushik8e644982015-09-23 12:18:54 +05306526 {
6527 hddLog(LOGE, FL("per pkt stats not enabled"));
6528 return -EINVAL;
6529 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306530
Sushant Kaushik33200572015-08-05 16:46:20 +05306531 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306532 return 0;
6533}
6534
6535/**
6536 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6537 * or disable the collection of packet statistics from the firmware
6538 * @wiphy: WIPHY structure pointer
6539 * @wdev: Wireless device structure pointer
6540 * @data: Pointer to the data received
6541 * @data_len: Length of the data received
6542 *
6543 * This function is used to enable or disable the collection of packet
6544 * statistics from the firmware
6545 *
6546 * Return: 0 on success and errno on failure
6547 */
6548static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6549 struct wireless_dev *wdev,
6550 const void *data,
6551 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306552{
6553 int ret = 0;
6554
6555 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306556
6557 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6558 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306559 vos_ssr_unprotect(__func__);
6560
6561 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306562}
6563
6564
Agarwal Ashish738843c2014-09-25 12:27:56 +05306565static const struct nla_policy
6566wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6567 +1] =
6568{
6569 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6570};
6571
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306572static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306573 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306574 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306575 int data_len)
6576{
6577 struct net_device *dev = wdev->netdev;
6578 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6579 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6580 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6581 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6582 eHalStatus status;
6583 u32 dfsFlag = 0;
6584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306585 ENTER();
6586
Agarwal Ashish738843c2014-09-25 12:27:56 +05306587 status = wlan_hdd_validate_context(pHddCtx);
6588 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306589 return -EINVAL;
6590 }
6591 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6592 data, data_len,
6593 wlan_hdd_set_no_dfs_flag_config_policy)) {
6594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6595 return -EINVAL;
6596 }
6597
6598 /* Parse and fetch required bandwidth kbps */
6599 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6601 return -EINVAL;
6602 }
6603
6604 dfsFlag = nla_get_u32(
6605 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6606 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6607 dfsFlag);
6608
6609 pHddCtx->disable_dfs_flag = dfsFlag;
6610
6611 sme_disable_dfs_channel(hHal, dfsFlag);
6612 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306613
6614 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306615 return 0;
6616}
Atul Mittal115287b2014-07-08 13:26:33 +05306617
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306618static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6619 struct wireless_dev *wdev,
6620 const void *data,
6621 int data_len)
6622{
6623 int ret = 0;
6624
6625 vos_ssr_protect(__func__);
6626 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6627 vos_ssr_unprotect(__func__);
6628
6629 return ret;
6630
6631}
6632
Mukul Sharma2a271632014-10-13 14:59:01 +05306633const struct
6634nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6635{
6636 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306637 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6638 .type = NLA_UNSPEC,
6639 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306640};
6641
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306642static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306643 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306644{
6645
6646 u8 bssid[6] = {0};
6647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6648 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6649 eHalStatus status = eHAL_STATUS_SUCCESS;
6650 v_U32_t isFwrRoamEnabled = FALSE;
6651 int ret;
6652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306653 ENTER();
6654
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306655 ret = wlan_hdd_validate_context(pHddCtx);
6656 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306657 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306658 }
6659
6660 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6661 data, data_len,
6662 qca_wlan_vendor_attr);
6663 if (ret){
6664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6665 return -EINVAL;
6666 }
6667
6668 /* Parse and fetch Enable flag */
6669 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6671 return -EINVAL;
6672 }
6673
6674 isFwrRoamEnabled = nla_get_u32(
6675 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6676
6677 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6678
6679 /* Parse and fetch bssid */
6680 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6682 return -EINVAL;
6683 }
6684
6685 memcpy(bssid, nla_data(
6686 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6687 sizeof(bssid));
6688 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6689
6690 //Update roaming
6691 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306692 if (!HAL_STATUS_SUCCESS(status)) {
6693 hddLog(LOGE,
6694 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6695 return -EINVAL;
6696 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306697 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306698 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306699}
6700
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306701static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6702 struct wireless_dev *wdev, const void *data, int data_len)
6703{
6704 int ret = 0;
6705
6706 vos_ssr_protect(__func__);
6707 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6708 vos_ssr_unprotect(__func__);
6709
6710 return ret;
6711}
6712
Sushant Kaushik847890c2015-09-28 16:05:17 +05306713static const struct
6714nla_policy
6715qca_wlan_vendor_get_wifi_info_policy[
6716 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6717 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6718 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6719};
6720
6721
6722/**
6723 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6724 * @wiphy: pointer to wireless wiphy structure.
6725 * @wdev: pointer to wireless_dev structure.
6726 * @data: Pointer to the data to be passed via vendor interface
6727 * @data_len:Length of the data to be passed
6728 *
6729 * This is called when wlan driver needs to send wifi driver related info
6730 * (driver/fw version) to the user space application upon request.
6731 *
6732 * Return: Return the Success or Failure code.
6733 */
6734static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6735 struct wireless_dev *wdev,
6736 const void *data, int data_len)
6737{
6738 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6739 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6740 tSirVersionString version;
6741 uint32 version_len;
6742 uint8 attr;
6743 int status;
6744 struct sk_buff *reply_skb = NULL;
6745
6746 if (VOS_FTM_MODE == hdd_get_conparam()) {
6747 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6748 return -EINVAL;
6749 }
6750
6751 status = wlan_hdd_validate_context(hdd_ctx);
6752 if (0 != status) {
6753 hddLog(LOGE, FL("HDD context is not valid"));
6754 return -EINVAL;
6755 }
6756
6757 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6758 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6759 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6760 return -EINVAL;
6761 }
6762
6763 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6764 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6765 QWLAN_VERSIONSTR);
6766 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6767 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6768 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6769 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6770 hdd_ctx->fw_Version);
6771 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6772 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6773 } else {
6774 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6775 return -EINVAL;
6776 }
6777
6778 version_len = strlen(version);
6779 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6780 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6781 if (!reply_skb) {
6782 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6783 return -ENOMEM;
6784 }
6785
6786 if (nla_put(reply_skb, attr, version_len, version)) {
6787 hddLog(LOGE, FL("nla put fail"));
6788 kfree_skb(reply_skb);
6789 return -EINVAL;
6790 }
6791
6792 return cfg80211_vendor_cmd_reply(reply_skb);
6793}
6794
6795/**
6796 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6797 * @wiphy: pointer to wireless wiphy structure.
6798 * @wdev: pointer to wireless_dev structure.
6799 * @data: Pointer to the data to be passed via vendor interface
6800 * @data_len:Length of the data to be passed
6801 * @data_len: Length of the data received
6802 *
6803 * This function is used to enable or disable the collection of packet
6804 * statistics from the firmware
6805 *
6806 * Return: 0 on success and errno on failure
6807 */
6808
6809static int
6810wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6811 struct wireless_dev *wdev,
6812 const void *data, int data_len)
6813
6814
6815{
6816 int ret = 0;
6817
6818 vos_ssr_protect(__func__);
6819 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6820 wdev, data, data_len);
6821 vos_ssr_unprotect(__func__);
6822
6823 return ret;
6824}
6825
6826
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306827/*
6828 * define short names for the global vendor params
6829 * used by __wlan_hdd_cfg80211_monitor_rssi()
6830 */
6831#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6832#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6833#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6834#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6835#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6836
6837/**---------------------------------------------------------------------------
6838
6839 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6840 monitor start is completed successfully.
6841
6842 \return - None
6843
6844 --------------------------------------------------------------------------*/
6845void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6846{
6847 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6848
6849 if (NULL == pHddCtx)
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR,
6852 "%s: HDD context is NULL",__func__);
6853 return;
6854 }
6855
6856 if (VOS_STATUS_SUCCESS == status)
6857 {
6858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6859 }
6860 else
6861 {
6862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6863 }
6864
6865 return;
6866}
6867
6868/**---------------------------------------------------------------------------
6869
6870 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6871 stop is completed successfully.
6872
6873 \return - None
6874
6875 --------------------------------------------------------------------------*/
6876void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6877{
6878 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6879
6880 if (NULL == pHddCtx)
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR,
6883 "%s: HDD context is NULL",__func__);
6884 return;
6885 }
6886
6887 if (VOS_STATUS_SUCCESS == status)
6888 {
6889 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6890 }
6891 else
6892 {
6893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6894 }
6895
6896 return;
6897}
6898
6899/**
6900 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6901 * @wiphy: Pointer to wireless phy
6902 * @wdev: Pointer to wireless device
6903 * @data: Pointer to data
6904 * @data_len: Data length
6905 *
6906 * Return: 0 on success, negative errno on failure
6907 */
6908
6909static int
6910__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6911 struct wireless_dev *wdev,
6912 const void *data,
6913 int data_len)
6914{
6915 struct net_device *dev = wdev->netdev;
6916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6917 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6918 hdd_station_ctx_t *pHddStaCtx;
6919 struct nlattr *tb[PARAM_MAX + 1];
6920 tpSirRssiMonitorReq pReq;
6921 eHalStatus status;
6922 int ret;
6923 uint32_t control;
6924 static const struct nla_policy policy[PARAM_MAX + 1] = {
6925 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6926 [PARAM_CONTROL] = { .type = NLA_U32 },
6927 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6928 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6929 };
6930
6931 ENTER();
6932
6933 ret = wlan_hdd_validate_context(hdd_ctx);
6934 if (0 != ret) {
6935 return -EINVAL;
6936 }
6937
6938 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6939 hddLog(LOGE, FL("Not in Connected state!"));
6940 return -ENOTSUPP;
6941 }
6942
6943 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6944 hddLog(LOGE, FL("Invalid ATTR"));
6945 return -EINVAL;
6946 }
6947
6948 if (!tb[PARAM_REQUEST_ID]) {
6949 hddLog(LOGE, FL("attr request id failed"));
6950 return -EINVAL;
6951 }
6952
6953 if (!tb[PARAM_CONTROL]) {
6954 hddLog(LOGE, FL("attr control failed"));
6955 return -EINVAL;
6956 }
6957
6958 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6959
6960 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6961 if(NULL == pReq)
6962 {
6963 hddLog(LOGE,
6964 FL("vos_mem_alloc failed "));
6965 return eHAL_STATUS_FAILED_ALLOC;
6966 }
6967 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6968
6969 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6970 pReq->sessionId = pAdapter->sessionId;
6971 pReq->rssiMonitorCbContext = hdd_ctx;
6972 control = nla_get_u32(tb[PARAM_CONTROL]);
6973 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6974
6975 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6976 pReq->requestId, pReq->sessionId, control);
6977
6978 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6979 if (!tb[PARAM_MIN_RSSI]) {
6980 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306981 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306982 }
6983
6984 if (!tb[PARAM_MAX_RSSI]) {
6985 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306986 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306987 }
6988
6989 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6990 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6991 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6992
6993 if (!(pReq->minRssi < pReq->maxRssi)) {
6994 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6995 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306996 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306997 }
6998 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6999 pReq->minRssi, pReq->maxRssi);
7000 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
7001
7002 }
7003 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
7004 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
7005 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
7006 }
7007 else {
7008 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307009 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307010 }
7011
7012 if (!HAL_STATUS_SUCCESS(status)) {
7013 hddLog(LOGE,
7014 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307015 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307016 }
7017
7018 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307019fail:
7020 vos_mem_free(pReq);
7021 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307022}
7023
7024/*
7025 * done with short names for the global vendor params
7026 * used by __wlan_hdd_cfg80211_monitor_rssi()
7027 */
7028#undef PARAM_MAX
7029#undef PARAM_CONTROL
7030#undef PARAM_REQUEST_ID
7031#undef PARAM_MAX_RSSI
7032#undef PARAM_MIN_RSSI
7033
7034/**
7035 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7036 * @wiphy: wiphy structure pointer
7037 * @wdev: Wireless device structure pointer
7038 * @data: Pointer to the data received
7039 * @data_len: Length of @data
7040 *
7041 * Return: 0 on success; errno on failure
7042 */
7043static int
7044wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7045 const void *data, int data_len)
7046{
7047 int ret;
7048
7049 vos_ssr_protect(__func__);
7050 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7051 vos_ssr_unprotect(__func__);
7052
7053 return ret;
7054}
7055
7056/**
7057 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7058 * @hddctx: HDD context
7059 * @data: rssi breached event data
7060 *
7061 * This function reads the rssi breached event %data and fill in the skb with
7062 * NL attributes and send up the NL event.
7063 * This callback execute in atomic context and must not invoke any
7064 * blocking calls.
7065 *
7066 * Return: none
7067 */
7068void hdd_rssi_threshold_breached_cb(void *hddctx,
7069 struct rssi_breach_event *data)
7070{
7071 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7072 int status;
7073 struct sk_buff *skb;
7074
7075 ENTER();
7076 status = wlan_hdd_validate_context(pHddCtx);
7077
7078 if (0 != status) {
7079 return;
7080 }
7081
7082 if (!data) {
7083 hddLog(LOGE, FL("data is null"));
7084 return;
7085 }
7086
7087 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7089 NULL,
7090#endif
7091 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7092 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7093 GFP_KERNEL);
7094
7095 if (!skb) {
7096 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7097 return;
7098 }
7099
7100 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7101 data->request_id, data->curr_rssi);
7102 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7103 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7104
7105 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7106 data->request_id) ||
7107 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7108 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7109 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7110 data->curr_rssi)) {
7111 hddLog(LOGE, FL("nla put fail"));
7112 goto fail;
7113 }
7114
7115 cfg80211_vendor_event(skb, GFP_KERNEL);
7116 return;
7117
7118fail:
7119 kfree_skb(skb);
7120 return;
7121}
7122
7123
7124
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307125/**
7126 * __wlan_hdd_cfg80211_setband() - set band
7127 * @wiphy: Pointer to wireless phy
7128 * @wdev: Pointer to wireless device
7129 * @data: Pointer to data
7130 * @data_len: Data length
7131 *
7132 * Return: 0 on success, negative errno on failure
7133 */
7134static int
7135__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7136 struct wireless_dev *wdev,
7137 const void *data,
7138 int data_len)
7139{
7140 struct net_device *dev = wdev->netdev;
7141 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7142 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7143 int ret;
7144 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7145 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7146
7147 ENTER();
7148
7149 ret = wlan_hdd_validate_context(hdd_ctx);
7150 if (0 != ret) {
7151 hddLog(LOGE, FL("HDD context is not valid"));
7152 return ret;
7153 }
7154
7155 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7156 policy)) {
7157 hddLog(LOGE, FL("Invalid ATTR"));
7158 return -EINVAL;
7159 }
7160
7161 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7162 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7163 return -EINVAL;
7164 }
7165
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307166 hdd_ctx->isSetBandByNL = TRUE;
7167 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307168 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307169 hdd_ctx->isSetBandByNL = FALSE;
7170
7171 EXIT();
7172 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307173}
7174
7175/**
7176 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7177 * @wiphy: wiphy structure pointer
7178 * @wdev: Wireless device structure pointer
7179 * @data: Pointer to the data received
7180 * @data_len: Length of @data
7181 *
7182 * Return: 0 on success; errno on failure
7183 */
7184static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7185 struct wireless_dev *wdev,
7186 const void *data,
7187 int data_len)
7188{
7189 int ret = 0;
7190
7191 vos_ssr_protect(__func__);
7192 ret = __wlan_hdd_cfg80211_setband(wiphy,
7193 wdev, data, data_len);
7194 vos_ssr_unprotect(__func__);
7195
7196 return ret;
7197}
7198
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307199#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7200/**
7201 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7202 * @hdd_ctx: HDD context
7203 * @request_id: [input] request id
7204 * @pattern_id: [output] pattern id
7205 *
7206 * This function loops through request id to pattern id array
7207 * if the slot is available, store the request id and return pattern id
7208 * if entry exists, return the pattern id
7209 *
7210 * Return: 0 on success and errno on failure
7211 */
7212static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7213 uint32_t request_id,
7214 uint8_t *pattern_id)
7215{
7216 uint32_t i;
7217
7218 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7219 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7220 {
7221 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7222 {
7223 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7224 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7225 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7226 return 0;
7227 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7228 request_id) {
7229 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7230 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7231 return 0;
7232 }
7233 }
7234 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7235 return -EINVAL;
7236}
7237
7238/**
7239 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7240 * @hdd_ctx: HDD context
7241 * @request_id: [input] request id
7242 * @pattern_id: [output] pattern id
7243 *
7244 * This function loops through request id to pattern id array
7245 * reset request id to 0 (slot available again) and
7246 * return pattern id
7247 *
7248 * Return: 0 on success and errno on failure
7249 */
7250static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7251 uint32_t request_id,
7252 uint8_t *pattern_id)
7253{
7254 uint32_t i;
7255
7256 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7257 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7258 {
7259 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7260 {
7261 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7262 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7263 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7264 return 0;
7265 }
7266 }
7267 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7268 return -EINVAL;
7269}
7270
7271
7272/*
7273 * define short names for the global vendor params
7274 * used by __wlan_hdd_cfg80211_offloaded_packets()
7275 */
7276#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7277#define PARAM_REQUEST_ID \
7278 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7279#define PARAM_CONTROL \
7280 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7281#define PARAM_IP_PACKET \
7282 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7283#define PARAM_SRC_MAC_ADDR \
7284 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7285#define PARAM_DST_MAC_ADDR \
7286 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7287#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7288
7289/**
7290 * wlan_hdd_add_tx_ptrn() - add tx pattern
7291 * @adapter: adapter pointer
7292 * @hdd_ctx: hdd context
7293 * @tb: nl attributes
7294 *
7295 * This function reads the NL attributes and forms a AddTxPtrn message
7296 * posts it to SME.
7297 *
7298 */
7299static int
7300wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7301 struct nlattr **tb)
7302{
7303 struct sSirAddPeriodicTxPtrn *add_req;
7304 eHalStatus status;
7305 uint32_t request_id, ret, len;
7306 uint8_t pattern_id = 0;
7307 v_MACADDR_t dst_addr;
7308 uint16_t eth_type = htons(ETH_P_IP);
7309
7310 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7311 {
7312 hddLog(LOGE, FL("Not in Connected state!"));
7313 return -ENOTSUPP;
7314 }
7315
7316 add_req = vos_mem_malloc(sizeof(*add_req));
7317 if (!add_req)
7318 {
7319 hddLog(LOGE, FL("memory allocation failed"));
7320 return -ENOMEM;
7321 }
7322
7323 /* Parse and fetch request Id */
7324 if (!tb[PARAM_REQUEST_ID])
7325 {
7326 hddLog(LOGE, FL("attr request id failed"));
7327 goto fail;
7328 }
7329
7330 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7331 hddLog(LOG1, FL("Request Id: %u"), request_id);
7332 if (request_id == 0)
7333 {
7334 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307335 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307336 }
7337
7338 if (!tb[PARAM_PERIOD])
7339 {
7340 hddLog(LOGE, FL("attr period failed"));
7341 goto fail;
7342 }
7343 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7344 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7345 if (add_req->usPtrnIntervalMs == 0)
7346 {
7347 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7348 goto fail;
7349 }
7350
7351 if (!tb[PARAM_SRC_MAC_ADDR])
7352 {
7353 hddLog(LOGE, FL("attr source mac address failed"));
7354 goto fail;
7355 }
7356 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7357 VOS_MAC_ADDR_SIZE);
7358 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7359 MAC_ADDR_ARRAY(add_req->macAddress));
7360
7361 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7362 VOS_MAC_ADDR_SIZE))
7363 {
7364 hddLog(LOGE,
7365 FL("input src mac address and connected ap bssid are different"));
7366 goto fail;
7367 }
7368
7369 if (!tb[PARAM_DST_MAC_ADDR])
7370 {
7371 hddLog(LOGE, FL("attr dst mac address failed"));
7372 goto fail;
7373 }
7374 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7375 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7376 MAC_ADDR_ARRAY(dst_addr.bytes));
7377
7378 if (!tb[PARAM_IP_PACKET])
7379 {
7380 hddLog(LOGE, FL("attr ip packet failed"));
7381 goto fail;
7382 }
7383 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7384 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7385
7386 if (add_req->ucPtrnSize < 0 ||
7387 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7388 HDD_ETH_HEADER_LEN))
7389 {
7390 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7391 add_req->ucPtrnSize);
7392 goto fail;
7393 }
7394
7395 len = 0;
7396 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7397 len += VOS_MAC_ADDR_SIZE;
7398 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7399 VOS_MAC_ADDR_SIZE);
7400 len += VOS_MAC_ADDR_SIZE;
7401 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7402 len += 2;
7403
7404 /*
7405 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7406 * ------------------------------------------------------------
7407 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7408 * ------------------------------------------------------------
7409 */
7410 vos_mem_copy(&add_req->ucPattern[len],
7411 nla_data(tb[PARAM_IP_PACKET]),
7412 add_req->ucPtrnSize);
7413 add_req->ucPtrnSize += len;
7414
7415 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7416 add_req->ucPattern, add_req->ucPtrnSize);
7417
7418 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7419 if (ret)
7420 {
7421 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7422 goto fail;
7423 }
7424 add_req->ucPtrnId = pattern_id;
7425 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7426
7427 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7428 if (!HAL_STATUS_SUCCESS(status))
7429 {
7430 hddLog(LOGE,
7431 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7432 goto fail;
7433 }
7434
7435 EXIT();
7436 vos_mem_free(add_req);
7437 return 0;
7438
7439fail:
7440 vos_mem_free(add_req);
7441 return -EINVAL;
7442}
7443
7444/**
7445 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7446 * @adapter: adapter pointer
7447 * @hdd_ctx: hdd context
7448 * @tb: nl attributes
7449 *
7450 * This function reads the NL attributes and forms a DelTxPtrn message
7451 * posts it to SME.
7452 *
7453 */
7454static int
7455wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7456 struct nlattr **tb)
7457{
7458 struct sSirDelPeriodicTxPtrn *del_req;
7459 eHalStatus status;
7460 uint32_t request_id, ret;
7461 uint8_t pattern_id = 0;
7462
7463 /* Parse and fetch request Id */
7464 if (!tb[PARAM_REQUEST_ID])
7465 {
7466 hddLog(LOGE, FL("attr request id failed"));
7467 return -EINVAL;
7468 }
7469 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7470 if (request_id == 0)
7471 {
7472 hddLog(LOGE, FL("request_id cannot be zero"));
7473 return -EINVAL;
7474 }
7475
7476 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7477 if (ret)
7478 {
7479 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7480 return -EINVAL;
7481 }
7482
7483 del_req = vos_mem_malloc(sizeof(*del_req));
7484 if (!del_req)
7485 {
7486 hddLog(LOGE, FL("memory allocation failed"));
7487 return -ENOMEM;
7488 }
7489
7490 vos_mem_set(del_req, sizeof(*del_req), 0);
7491 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7492 VOS_MAC_ADDR_SIZE);
7493 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7494 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7495 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7496 request_id, pattern_id, del_req->ucPatternIdBitmap);
7497
7498 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7499 if (!HAL_STATUS_SUCCESS(status))
7500 {
7501 hddLog(LOGE,
7502 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7503 goto fail;
7504 }
7505
7506 EXIT();
7507 vos_mem_free(del_req);
7508 return 0;
7509
7510fail:
7511 vos_mem_free(del_req);
7512 return -EINVAL;
7513}
7514
7515
7516/**
7517 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7518 * @wiphy: Pointer to wireless phy
7519 * @wdev: Pointer to wireless device
7520 * @data: Pointer to data
7521 * @data_len: Data length
7522 *
7523 * Return: 0 on success, negative errno on failure
7524 */
7525static int
7526__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7527 struct wireless_dev *wdev,
7528 const void *data,
7529 int data_len)
7530{
7531 struct net_device *dev = wdev->netdev;
7532 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7533 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7534 struct nlattr *tb[PARAM_MAX + 1];
7535 uint8_t control;
7536 int ret;
7537 static const struct nla_policy policy[PARAM_MAX + 1] =
7538 {
7539 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7540 [PARAM_CONTROL] = { .type = NLA_U32 },
7541 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7542 .len = VOS_MAC_ADDR_SIZE },
7543 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7544 .len = VOS_MAC_ADDR_SIZE },
7545 [PARAM_PERIOD] = { .type = NLA_U32 },
7546 };
7547
7548 ENTER();
7549
7550 ret = wlan_hdd_validate_context(hdd_ctx);
7551 if (0 != ret)
7552 {
7553 hddLog(LOGE, FL("HDD context is not valid"));
7554 return ret;
7555 }
7556
7557 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7558 {
7559 hddLog(LOGE,
7560 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7561 return -ENOTSUPP;
7562 }
7563
7564 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7565 {
7566 hddLog(LOGE, FL("Invalid ATTR"));
7567 return -EINVAL;
7568 }
7569
7570 if (!tb[PARAM_CONTROL])
7571 {
7572 hddLog(LOGE, FL("attr control failed"));
7573 return -EINVAL;
7574 }
7575 control = nla_get_u32(tb[PARAM_CONTROL]);
7576 hddLog(LOG1, FL("Control: %d"), control);
7577
7578 if (control == WLAN_START_OFFLOADED_PACKETS)
7579 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7580 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7581 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7582 else
7583 {
7584 hddLog(LOGE, FL("Invalid control: %d"), control);
7585 return -EINVAL;
7586 }
7587}
7588
7589/*
7590 * done with short names for the global vendor params
7591 * used by __wlan_hdd_cfg80211_offloaded_packets()
7592 */
7593#undef PARAM_MAX
7594#undef PARAM_REQUEST_ID
7595#undef PARAM_CONTROL
7596#undef PARAM_IP_PACKET
7597#undef PARAM_SRC_MAC_ADDR
7598#undef PARAM_DST_MAC_ADDR
7599#undef PARAM_PERIOD
7600
7601/**
7602 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7603 * @wiphy: wiphy structure pointer
7604 * @wdev: Wireless device structure pointer
7605 * @data: Pointer to the data received
7606 * @data_len: Length of @data
7607 *
7608 * Return: 0 on success; errno on failure
7609 */
7610static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7611 struct wireless_dev *wdev,
7612 const void *data,
7613 int data_len)
7614{
7615 int ret = 0;
7616
7617 vos_ssr_protect(__func__);
7618 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7619 wdev, data, data_len);
7620 vos_ssr_unprotect(__func__);
7621
7622 return ret;
7623}
7624#endif
7625
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307626static const struct
7627nla_policy
7628qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307629 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7630 .type = NLA_BINARY,
7631 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307632};
7633
7634/**
7635 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7636 * get link properties like nss, rate flags and operating frequency for
7637 * the connection with the given peer.
7638 * @wiphy: WIPHY structure pointer
7639 * @wdev: Wireless device structure pointer
7640 * @data: Pointer to the data received
7641 * @data_len: Length of the data received
7642 *
7643 * This function return the above link properties on success.
7644 *
7645 * Return: 0 on success and errno on failure
7646 */
7647static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7648 struct wireless_dev *wdev,
7649 const void *data,
7650 int data_len)
7651{
7652 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7653 struct net_device *dev = wdev->netdev;
7654 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7655 hdd_station_ctx_t *hdd_sta_ctx;
7656 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7657 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7658 uint32_t sta_id;
7659 struct sk_buff *reply_skb;
7660 uint32_t rate_flags = 0;
7661 uint8_t nss;
7662 uint8_t final_rate_flags = 0;
7663 uint32_t freq;
7664 v_CONTEXT_t pVosContext = NULL;
7665 ptSapContext pSapCtx = NULL;
7666
7667 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7669 return -EINVAL;
7670 }
7671
7672 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7673 qca_wlan_vendor_attr_policy)) {
7674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7675 return -EINVAL;
7676 }
7677
7678 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7679 hddLog(VOS_TRACE_LEVEL_ERROR,
7680 FL("Attribute peerMac not provided for mode=%d"),
7681 adapter->device_mode);
7682 return -EINVAL;
7683 }
7684
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307685 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7686 hddLog(VOS_TRACE_LEVEL_ERROR,
7687 FL("Attribute peerMac is invalid=%d"),
7688 adapter->device_mode);
7689 return -EINVAL;
7690 }
7691
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307692 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7693 sizeof(peer_mac));
7694 hddLog(VOS_TRACE_LEVEL_INFO,
7695 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7696 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7697
7698 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7699 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7700 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7701 if ((hdd_sta_ctx->conn_info.connState !=
7702 eConnectionState_Associated) ||
7703 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7704 VOS_MAC_ADDRESS_LEN)) {
7705 hddLog(VOS_TRACE_LEVEL_ERROR,
7706 FL("Not Associated to mac "MAC_ADDRESS_STR),
7707 MAC_ADDR_ARRAY(peer_mac));
7708 return -EINVAL;
7709 }
7710
7711 nss = 1; //pronto supports only one spatial stream
7712 freq = vos_chan_to_freq(
7713 hdd_sta_ctx->conn_info.operationChannel);
7714 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7715
7716 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7717 adapter->device_mode == WLAN_HDD_SOFTAP) {
7718
7719 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7720 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7721 if(pSapCtx == NULL){
7722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7723 FL("psapCtx is NULL"));
7724 return -ENOENT;
7725 }
7726
7727
7728 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7729 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7730 !vos_is_macaddr_broadcast(
7731 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7732 vos_mem_compare(
7733 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7734 peer_mac, VOS_MAC_ADDRESS_LEN))
7735 break;
7736 }
7737
7738 if (WLAN_MAX_STA_COUNT == sta_id) {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 FL("No active peer with mac="MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(peer_mac));
7742 return -EINVAL;
7743 }
7744
7745 nss = 1; //pronto supports only one spatial stream
7746 freq = vos_chan_to_freq(
7747 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7748 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7749 } else {
7750 hddLog(VOS_TRACE_LEVEL_ERROR,
7751 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7752 MAC_ADDR_ARRAY(peer_mac));
7753 return -EINVAL;
7754 }
7755
7756 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7757 if (rate_flags & eHAL_TX_RATE_VHT80) {
7758 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307759#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7760 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307761 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307763 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7764 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307765#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7766 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307768#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307769 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7770 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7771 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7772 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307773#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7774 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307775 if (rate_flags & eHAL_TX_RATE_HT40)
7776 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307777#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307778 }
7779
7780 if (rate_flags & eHAL_TX_RATE_SGI) {
7781 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7782 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7783 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7784 }
7785 }
7786
7787 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7788 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7789
7790 if (NULL == reply_skb) {
7791 hddLog(VOS_TRACE_LEVEL_ERROR,
7792 FL("getLinkProperties: skb alloc failed"));
7793 return -EINVAL;
7794 }
7795
7796 if (nla_put_u8(reply_skb,
7797 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7798 nss) ||
7799 nla_put_u8(reply_skb,
7800 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7801 final_rate_flags) ||
7802 nla_put_u32(reply_skb,
7803 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7804 freq)) {
7805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7806 kfree_skb(reply_skb);
7807 return -EINVAL;
7808 }
7809
7810 return cfg80211_vendor_cmd_reply(reply_skb);
7811}
7812
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307813#define BEACON_MISS_THRESH_2_4 \
7814 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7815#define BEACON_MISS_THRESH_5_0 \
7816 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307817#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7818#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7819#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7820#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307821#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7822 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307823#define PARAM_FORCE_RSN_IE \
7824 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307825/*
7826 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7827 * @hdd_ctx: hdd context
7828 * @enable: Value received in the command, 1 for disable and 2 for enable
7829 *
7830 * Return: void
7831 */
7832static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7833{
7834 if (!hdd_ctx) {
7835 hddLog(LOGE, "hdd_ctx NULL");
7836 return;
7837 }
7838
7839 sme_set_qpower(hdd_ctx->hHal, enable);
7840}
7841
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307842/**
7843 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7844 * vendor command
7845 *
7846 * @wiphy: wiphy device pointer
7847 * @wdev: wireless device pointer
7848 * @data: Vendor command data buffer
7849 * @data_len: Buffer length
7850 *
7851 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7852 *
7853 * Return: EOK or other error codes.
7854 */
7855
7856static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7857 struct wireless_dev *wdev,
7858 const void *data,
7859 int data_len)
7860{
7861 struct net_device *dev = wdev->netdev;
7862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7863 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7864 hdd_station_ctx_t *pHddStaCtx;
7865 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7866 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307867 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307868 eHalStatus status;
7869 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307870 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307871 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307872
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307873 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7874 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7875 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307876 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7877 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7878 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307879 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7880 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307881 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307882 };
7883
7884 ENTER();
7885
7886 if (VOS_FTM_MODE == hdd_get_conparam()) {
7887 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7888 return -EINVAL;
7889 }
7890
7891 ret_val = wlan_hdd_validate_context(pHddCtx);
7892 if (ret_val) {
7893 return ret_val;
7894 }
7895
7896 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7897
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307898 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7899 hddLog(LOGE, FL("Invalid ATTR"));
7900 return -EINVAL;
7901 }
7902
7903 /* check the Wifi Capability */
7904 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7905 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7906 {
7907 hddLog(VOS_TRACE_LEVEL_ERROR,
7908 FL("WIFICONFIG not supported by Firmware"));
7909 return -EINVAL;
7910 }
7911
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307912 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7913 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7914 modifyRoamParamsReq.value =
7915 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7916
7917 if (eHAL_STATUS_SUCCESS !=
7918 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7919 {
7920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7921 ret_val = -EINVAL;
7922 }
7923 return ret_val;
7924 }
7925
7926 /* Moved this down in order to provide provision to set beacon
7927 * miss penalty count irrespective of connection state.
7928 */
7929 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7930 hddLog(LOGE, FL("Not in Connected state!"));
7931 return -ENOTSUPP;
7932 }
7933
7934 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307935
7936 if (!pReq) {
7937 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7938 "%s: Not able to allocate memory for tSetWifiConfigParams",
7939 __func__);
7940 return eHAL_STATUS_E_MALLOC_FAILED;
7941 }
7942
7943 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7944
7945 pReq->sessionId = pAdapter->sessionId;
7946 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7947
7948 if (tb[PARAM_MODULATED_DTIM]) {
7949 pReq->paramValue = nla_get_u32(
7950 tb[PARAM_MODULATED_DTIM]);
7951 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7952 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307953 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307954 hdd_set_pwrparams(pHddCtx);
7955 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7956 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7957
7958 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7959 iw_full_power_cbfn, pAdapter,
7960 eSME_FULL_PWR_NEEDED_BY_HDD);
7961 }
7962 else
7963 {
7964 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7965 }
7966 }
7967
7968 if (tb[PARAM_STATS_AVG_FACTOR]) {
7969 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7970 pReq->paramValue = nla_get_u16(
7971 tb[PARAM_STATS_AVG_FACTOR]);
7972 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7973 pReq->paramType, pReq->paramValue);
7974 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7975
7976 if (eHAL_STATUS_SUCCESS != status)
7977 {
7978 vos_mem_free(pReq);
7979 pReq = NULL;
7980 ret_val = -EPERM;
7981 return ret_val;
7982 }
7983 }
7984
7985
7986 if (tb[PARAM_GUARD_TIME]) {
7987 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7988 pReq->paramValue = nla_get_u32(
7989 tb[PARAM_GUARD_TIME]);
7990 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7991 pReq->paramType, pReq->paramValue);
7992 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7993
7994 if (eHAL_STATUS_SUCCESS != status)
7995 {
7996 vos_mem_free(pReq);
7997 pReq = NULL;
7998 ret_val = -EPERM;
7999 return ret_val;
8000 }
8001
8002 }
8003
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05308004 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
8005 hb_thresh_val = nla_get_u8(
8006 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
8007
8008 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
8009 hb_thresh_val);
8010 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8011 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8012 NULL, eANI_BOOLEAN_FALSE);
8013
8014 status = sme_update_hb_threshold(
8015 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8016 WNI_CFG_HEART_BEAT_THRESHOLD,
8017 hb_thresh_val, eCSR_BAND_24);
8018 if (eHAL_STATUS_SUCCESS != status) {
8019 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8020 vos_mem_free(pReq);
8021 pReq = NULL;
8022 return -EPERM;
8023 }
8024 }
8025
8026 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8027 hb_thresh_val = nla_get_u8(
8028 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8029
8030 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8031 hb_thresh_val);
8032 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8033 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8034 NULL, eANI_BOOLEAN_FALSE);
8035
8036 status = sme_update_hb_threshold(
8037 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8038 WNI_CFG_HEART_BEAT_THRESHOLD,
8039 hb_thresh_val, eCSR_BAND_5G);
8040 if (eHAL_STATUS_SUCCESS != status) {
8041 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8042 vos_mem_free(pReq);
8043 pReq = NULL;
8044 return -EPERM;
8045 }
8046 }
8047
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308048 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8049 qpower = nla_get_u8(
8050 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8051
8052 if(qpower > 1) {
8053 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8054 vos_mem_free(pReq);
8055 pReq = NULL;
8056 return -EINVAL;
8057 }
8058 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8059 qpower++;
8060 hdd_set_qpower(pHddCtx, qpower);
8061 }
8062
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308063 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8064 pHddCtx->cfg_ini->force_rsne_override) {
8065 uint8_t force_rsne_override;
8066
8067 force_rsne_override =
8068 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8069 if (force_rsne_override > 1) {
8070 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8071 ret_val = -EINVAL;
8072 }
8073 pHddCtx->force_rsne_override = force_rsne_override;
8074 hddLog(LOG1, "force_rsne_override - %d",
8075 pHddCtx->force_rsne_override);
8076 }
8077
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308078 EXIT();
8079 return ret_val;
8080}
8081
8082/**
8083 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8084 * vendor command
8085 *
8086 * @wiphy: wiphy device pointer
8087 * @wdev: wireless device pointer
8088 * @data: Vendor command data buffer
8089 * @data_len: Buffer length
8090 *
8091 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8092 *
8093 * Return: EOK or other error codes.
8094 */
8095static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8096 struct wireless_dev *wdev,
8097 const void *data,
8098 int data_len)
8099{
8100 int ret;
8101
8102 vos_ssr_protect(__func__);
8103 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8104 data, data_len);
8105 vos_ssr_unprotect(__func__);
8106
8107 return ret;
8108}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308109
8110/*
8111 * define short names for the global vendor params
8112 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8113 */
8114#define STATS_SET_INVALID \
8115 QCA_ATTR_NUD_STATS_SET_INVALID
8116#define STATS_SET_START \
8117 QCA_ATTR_NUD_STATS_SET_START
8118#define STATS_GW_IPV4 \
8119 QCA_ATTR_NUD_STATS_GW_IPV4
8120#define STATS_SET_MAX \
8121 QCA_ATTR_NUD_STATS_SET_MAX
8122
8123const struct nla_policy
8124qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8125{
8126 [STATS_SET_START] = {.type = NLA_FLAG },
8127 [STATS_GW_IPV4] = {.type = NLA_U32 },
8128};
8129
8130/**
8131 * hdd_set_nud_stats_cb() - hdd callback api to get status
8132 * @data: pointer to adapter
8133 * @rsp: status
8134 *
8135 * Return: None
8136 */
8137static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8138{
8139
8140 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8141
8142 if (NULL == adapter)
8143 return;
8144
8145 if (VOS_STATUS_SUCCESS == rsp) {
8146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8147 "%s success received STATS_SET_START", __func__);
8148 } else {
8149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8150 "%s STATS_SET_START Failed!!", __func__);
8151 }
8152 return;
8153}
8154
8155/**
8156 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8157 * @wiphy: pointer to wireless wiphy structure.
8158 * @wdev: pointer to wireless_dev structure.
8159 * @data: pointer to apfind configuration data.
8160 * @data_len: the length in byte of apfind data.
8161 *
8162 * This is called when wlan driver needs to send arp stats to
8163 * firmware.
8164 *
8165 * Return: An error code or 0 on success.
8166 */
8167static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8168 struct wireless_dev *wdev,
8169 const void *data, int data_len)
8170{
8171 struct nlattr *tb[STATS_SET_MAX + 1];
8172 struct net_device *dev = wdev->netdev;
8173 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8174 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308175 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308176 setArpStatsParams arp_stats_params;
8177 int err = 0;
8178
8179 ENTER();
8180
8181 err = wlan_hdd_validate_context(hdd_ctx);
8182 if (0 != err)
8183 return err;
8184
8185 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8187 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8188 return -EINVAL;
8189 }
8190
8191 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8192 qca_wlan_vendor_set_nud_stats);
8193 if (err)
8194 {
8195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8196 "%s STATS_SET_START ATTR", __func__);
8197 return err;
8198 }
8199
8200 if (tb[STATS_SET_START])
8201 {
8202 if (!tb[STATS_GW_IPV4]) {
8203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8204 "%s STATS_SET_START CMD", __func__);
8205 return -EINVAL;
8206 }
8207 arp_stats_params.flag = true;
8208 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8209 } else {
8210 arp_stats_params.flag = false;
8211 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308212 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8214 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308215 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8216 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308217
8218 arp_stats_params.pkt_type = 1; // ARP packet type
8219
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308220 if (arp_stats_params.flag) {
8221 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8222 WLANTL_SetARPFWDatapath(pVosContext, true);
8223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8224 "%s Set FW in data path for ARP with tgt IP :%d",
8225 __func__, hdd_ctx->track_arp_ip);
8226 }
8227 else {
8228 WLANTL_SetARPFWDatapath(pVosContext, false);
8229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8230 "%s Remove FW from data path", __func__);
8231 }
8232
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308233 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8234 arp_stats_params.data_ctx = adapter;
8235
8236 if (eHAL_STATUS_SUCCESS !=
8237 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8239 "%s STATS_SET_START CMD Failed!!", __func__);
8240 return -EINVAL;
8241 }
8242
8243 EXIT();
8244
8245 return err;
8246}
8247
8248/**
8249 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8250 * @wiphy: pointer to wireless wiphy structure.
8251 * @wdev: pointer to wireless_dev structure.
8252 * @data: pointer to apfind configuration data.
8253 * @data_len: the length in byte of apfind data.
8254 *
8255 * This is called when wlan driver needs to send arp stats to
8256 * firmware.
8257 *
8258 * Return: An error code or 0 on success.
8259 */
8260static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8261 struct wireless_dev *wdev,
8262 const void *data, int data_len)
8263{
8264 int ret;
8265
8266 vos_ssr_protect(__func__);
8267 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8268 vos_ssr_unprotect(__func__);
8269
8270 return ret;
8271}
8272#undef STATS_SET_INVALID
8273#undef STATS_SET_START
8274#undef STATS_GW_IPV4
8275#undef STATS_SET_MAX
8276
8277/*
8278 * define short names for the global vendor params
8279 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8280 */
8281#define STATS_GET_INVALID \
8282 QCA_ATTR_NUD_STATS_SET_INVALID
8283#define COUNT_FROM_NETDEV \
8284 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8285#define COUNT_TO_LOWER_MAC \
8286 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8287#define RX_COUNT_BY_LOWER_MAC \
8288 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8289#define COUNT_TX_SUCCESS \
8290 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8291#define RSP_RX_COUNT_BY_LOWER_MAC \
8292 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8293#define RSP_RX_COUNT_BY_UPPER_MAC \
8294 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8295#define RSP_COUNT_TO_NETDEV \
8296 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8297#define RSP_COUNT_OUT_OF_ORDER_DROP \
8298 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8299#define AP_LINK_ACTIVE \
8300 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8301#define AP_LINK_DAD \
8302 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8303#define STATS_GET_MAX \
8304 QCA_ATTR_NUD_STATS_GET_MAX
8305
8306const struct nla_policy
8307qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8308{
8309 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8310 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8311 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8312 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8313 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8314 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8315 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8316 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8317 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8318 [AP_LINK_DAD] = {.type = NLA_FLAG },
8319};
8320
8321static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8322{
8323
8324 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308325 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308326 struct hdd_nud_stats_context *context;
8327 int status;
8328
8329 ENTER();
8330
8331 if (NULL == adapter)
8332 return;
8333
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308334 if (!rsp) {
8335 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308336 return;
8337 }
8338
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308339 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8340 status = wlan_hdd_validate_context(hdd_ctx);
8341 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308342 return;
8343 }
8344
8345 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8346 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8347 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8348 adapter->dad |= rsp->dad;
8349
8350 spin_lock(&hdd_context_lock);
8351 context = &hdd_ctx->nud_stats_context;
8352 complete(&context->response_event);
8353 spin_unlock(&hdd_context_lock);
8354
8355 return;
8356}
8357static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8358 struct wireless_dev *wdev,
8359 const void *data, int data_len)
8360{
8361 int err = 0;
8362 unsigned long rc;
8363 struct hdd_nud_stats_context *context;
8364 struct net_device *dev = wdev->netdev;
8365 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8366 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8367 getArpStatsParams arp_stats_params;
8368 struct sk_buff *skb;
8369
8370 ENTER();
8371
8372 err = wlan_hdd_validate_context(hdd_ctx);
8373 if (0 != err)
8374 return err;
8375
8376 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8377 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8378 arp_stats_params.data_ctx = adapter;
8379
8380 spin_lock(&hdd_context_lock);
8381 context = &hdd_ctx->nud_stats_context;
8382 INIT_COMPLETION(context->response_event);
8383 spin_unlock(&hdd_context_lock);
8384
8385 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8387 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8388 return -EINVAL;
8389 }
8390
8391 if (eHAL_STATUS_SUCCESS !=
8392 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8394 "%s STATS_SET_START CMD Failed!!", __func__);
8395 return -EINVAL;
8396 }
8397
8398 rc = wait_for_completion_timeout(&context->response_event,
8399 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8400 if (!rc)
8401 {
8402 hddLog(LOGE,
8403 FL("Target response timed out request "));
8404 return -ETIMEDOUT;
8405 }
8406
8407 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8408 WLAN_NUD_STATS_LEN);
8409 if (!skb)
8410 {
8411 hddLog(VOS_TRACE_LEVEL_ERROR,
8412 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8413 __func__);
8414 return -ENOMEM;
8415 }
8416
8417 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8418 adapter->hdd_stats.hddArpStats.txCount) ||
8419 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8420 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8421 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8422 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8423 nla_put_u16(skb, COUNT_TX_SUCCESS,
8424 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8425 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8426 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8427 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8428 adapter->hdd_stats.hddArpStats.rxCount) ||
8429 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8430 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8431 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8432 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8433 hddLog(LOGE, FL("nla put fail"));
8434 kfree_skb(skb);
8435 return -EINVAL;
8436 }
8437 if (adapter->con_status)
8438 nla_put_flag(skb, AP_LINK_ACTIVE);
8439 if (adapter->dad)
8440 nla_put_flag(skb, AP_LINK_DAD);
8441
8442 cfg80211_vendor_cmd_reply(skb);
8443 return err;
8444}
8445
8446static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8447 struct wireless_dev *wdev,
8448 const void *data, int data_len)
8449{
8450 int ret;
8451
8452 vos_ssr_protect(__func__);
8453 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8454 vos_ssr_unprotect(__func__);
8455
8456 return ret;
8457}
8458
8459#undef QCA_ATTR_NUD_STATS_SET_INVALID
8460#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8461#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8462#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8463#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8464#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8465#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8466#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8467#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8468#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8469#undef QCA_ATTR_NUD_STATS_GET_MAX
8470
8471
8472
Kapil Guptaee33bf12016-12-20 18:27:37 +05308473#ifdef WLAN_FEATURE_APFIND
8474/**
8475 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8476 * @wiphy: pointer to wireless wiphy structure.
8477 * @wdev: pointer to wireless_dev structure.
8478 * @data: pointer to apfind configuration data.
8479 * @data_len: the length in byte of apfind data.
8480 *
8481 * This is called when wlan driver needs to send APFIND configurations to
8482 * firmware.
8483 *
8484 * Return: An error code or 0 on success.
8485 */
8486static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8487 struct wireless_dev *wdev,
8488 const void *data, int data_len)
8489{
8490 struct sme_ap_find_request_req apfind_req;
8491 VOS_STATUS status;
8492 int ret_val;
8493 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8494
8495 ENTER();
8496
8497 ret_val = wlan_hdd_validate_context(hdd_ctx);
8498 if (ret_val)
8499 return ret_val;
8500
8501 if (VOS_FTM_MODE == hdd_get_conparam()) {
8502 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8503 return -EPERM;
8504 }
8505
8506 apfind_req.request_data_len = data_len;
8507 apfind_req.request_data = data;
8508
8509 status = sme_apfind_set_cmd(&apfind_req);
8510 if (VOS_STATUS_SUCCESS != status) {
8511 ret_val = -EIO;
8512 }
8513 return ret_val;
8514}
8515
8516/**
8517 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8518 * @wiphy: pointer to wireless wiphy structure.
8519 * @wdev: pointer to wireless_dev structure.
8520 * @data: pointer to apfind configuration data.
8521 * @data_len: the length in byte of apfind data.
8522 *
8523 * This is called when wlan driver needs to send APFIND configurations to
8524 * firmware.
8525 *
8526 * Return: An error code or 0 on success.
8527 */
8528static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8529 struct wireless_dev *wdev,
8530 const void *data, int data_len)
8531{
8532 int ret;
8533
8534 vos_ssr_protect(__func__);
8535 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8536 vos_ssr_unprotect(__func__);
8537
8538 return ret;
8539}
8540#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308541
8542/**
8543 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8544 * @wiphy: pointer to wireless wiphy structure.
8545 * @wdev: pointer to wireless_dev structure.
8546 * @data: Pointer to the data to be passed via vendor interface
8547 * @data_len:Length of the data to be passed
8548 *
8549 * This is called by userspace to know the supported logger features
8550 *
8551 * Return: Return the Success or Failure code.
8552 */
8553static int
8554__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8555 struct wireless_dev *wdev,
8556 const void *data, int data_len)
8557{
8558 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8559 int status;
8560 uint32_t features;
8561 struct sk_buff *reply_skb = NULL;
8562
8563 if (VOS_FTM_MODE == hdd_get_conparam()) {
8564 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8565 return -EINVAL;
8566 }
8567
8568 status = wlan_hdd_validate_context(hdd_ctx);
8569 if (0 != status)
8570 return -EINVAL;
8571
8572 features = 0;
8573
8574 if (hdd_is_memdump_supported())
8575 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8576
8577 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8578 hdd_ctx->cfg_ini->enableFatalEvent &&
8579 hdd_ctx->is_fatal_event_log_sup) {
8580 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8581 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8582 }
8583
8584 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8585 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8586 if (!reply_skb) {
8587 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8588 return -ENOMEM;
8589 }
8590
8591 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8592 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8593 features)) {
8594 hddLog(LOGE, FL("nla put fail"));
8595 kfree_skb(reply_skb);
8596 return -EINVAL;
8597 }
8598
8599 return cfg80211_vendor_cmd_reply(reply_skb);
8600}
8601
8602/**
8603 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8604 * @wiphy: pointer to wireless wiphy structure.
8605 * @wdev: pointer to wireless_dev structure.
8606 * @data: Pointer to the data to be passed via vendor interface
8607 * @data_len:Length of the data to be passed
8608 *
8609 * This is called by userspace to know the supported logger features
8610 *
8611 * Return: Return the Success or Failure code.
8612 */
8613static int
8614wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8615 struct wireless_dev *wdev,
8616 const void *data, int data_len)
8617{
8618 int ret;
8619
8620 vos_ssr_protect(__func__);
8621 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8622 data, data_len);
8623 vos_ssr_unprotect(__func__);
8624
8625 return ret;
8626}
8627
Sunil Duttc69bccb2014-05-26 21:30:20 +05308628const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8629{
Mukul Sharma2a271632014-10-13 14:59:01 +05308630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV |
8635 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308636 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308637 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308638
8639 {
8640 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8641 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8642 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8643 WIPHY_VENDOR_CMD_NEED_NETDEV |
8644 WIPHY_VENDOR_CMD_NEED_RUNNING,
8645 .doit = wlan_hdd_cfg80211_nan_request
8646 },
8647
Sunil Duttc69bccb2014-05-26 21:30:20 +05308648#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8649 {
8650 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8651 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8652 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8653 WIPHY_VENDOR_CMD_NEED_NETDEV |
8654 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308655 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308656 },
8657
8658 {
8659 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8660 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8661 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8662 WIPHY_VENDOR_CMD_NEED_NETDEV |
8663 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308664 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308665 },
8666
8667 {
8668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8671 WIPHY_VENDOR_CMD_NEED_NETDEV |
8672 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308673 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308674 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308675#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308676#ifdef WLAN_FEATURE_EXTSCAN
8677 {
8678 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8679 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8680 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8681 WIPHY_VENDOR_CMD_NEED_NETDEV |
8682 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308683 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308684 },
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308691 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308692 },
8693 {
8694 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8695 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
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_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308699 },
8700 {
8701 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8702 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8703 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8704 WIPHY_VENDOR_CMD_NEED_NETDEV |
8705 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308706 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308707 },
8708 {
8709 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8710 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8711 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8712 WIPHY_VENDOR_CMD_NEED_NETDEV |
8713 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308714 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308715 },
8716 {
8717 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8718 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8719 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8720 WIPHY_VENDOR_CMD_NEED_NETDEV |
8721 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308722 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308723 },
8724 {
8725 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8726 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8727 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8728 WIPHY_VENDOR_CMD_NEED_NETDEV |
8729 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308730 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308731 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308732#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308733/*EXT TDLS*/
8734 {
8735 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8736 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8737 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8738 WIPHY_VENDOR_CMD_NEED_NETDEV |
8739 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308740 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308741 },
8742 {
8743 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8744 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8745 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8746 WIPHY_VENDOR_CMD_NEED_NETDEV |
8747 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308748 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308749 },
8750 {
8751 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8752 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8753 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8754 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308755 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308756 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308757 {
8758 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8759 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8760 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8761 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308762 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308763 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308764 {
8765 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8766 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8767 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8768 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308769 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308770 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308771 {
8772 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8773 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8774 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8775 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308776 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308777 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308778 {
8779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8782 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308783 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308784 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308785 {
8786 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308787 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8788 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8789 WIPHY_VENDOR_CMD_NEED_NETDEV |
8790 WIPHY_VENDOR_CMD_NEED_RUNNING,
8791 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8792 },
8793 {
8794 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308795 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8796 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8797 WIPHY_VENDOR_CMD_NEED_NETDEV |
8798 WIPHY_VENDOR_CMD_NEED_RUNNING,
8799 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308800 },
8801 {
8802 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8803 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8804 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8805 WIPHY_VENDOR_CMD_NEED_NETDEV,
8806 .doit = wlan_hdd_cfg80211_wifi_logger_start
8807 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308808 {
8809 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8810 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8811 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8812 WIPHY_VENDOR_CMD_NEED_NETDEV|
8813 WIPHY_VENDOR_CMD_NEED_RUNNING,
8814 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308815 },
8816 {
8817 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8818 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8819 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8820 WIPHY_VENDOR_CMD_NEED_NETDEV |
8821 WIPHY_VENDOR_CMD_NEED_RUNNING,
8822 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308823 },
8824 {
8825 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8826 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8827 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8828 WIPHY_VENDOR_CMD_NEED_NETDEV |
8829 WIPHY_VENDOR_CMD_NEED_RUNNING,
8830 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308831 },
8832#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8833 {
8834 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8835 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8836 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8837 WIPHY_VENDOR_CMD_NEED_NETDEV |
8838 WIPHY_VENDOR_CMD_NEED_RUNNING,
8839 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308840 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308841#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308842 {
8843 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8844 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8845 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8846 WIPHY_VENDOR_CMD_NEED_NETDEV |
8847 WIPHY_VENDOR_CMD_NEED_RUNNING,
8848 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308849 },
8850 {
8851 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8852 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8853 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8854 WIPHY_VENDOR_CMD_NEED_NETDEV |
8855 WIPHY_VENDOR_CMD_NEED_RUNNING,
8856 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308857 },
8858#ifdef WLAN_FEATURE_APFIND
8859 {
8860 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8861 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8862 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8863 WIPHY_VENDOR_CMD_NEED_NETDEV,
8864 .doit = wlan_hdd_cfg80211_apfind_cmd
8865 },
8866#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308867 {
8868 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8869 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8870 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8871 WIPHY_VENDOR_CMD_NEED_NETDEV |
8872 WIPHY_VENDOR_CMD_NEED_RUNNING,
8873 .doit = wlan_hdd_cfg80211_set_nud_stats
8874 },
8875 {
8876 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8877 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8878 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8879 WIPHY_VENDOR_CMD_NEED_NETDEV |
8880 WIPHY_VENDOR_CMD_NEED_RUNNING,
8881 .doit = wlan_hdd_cfg80211_get_nud_stats
8882 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308883 {
8884 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8885 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8886 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8887 WIPHY_VENDOR_CMD_NEED_NETDEV |
8888 WIPHY_VENDOR_CMD_NEED_RUNNING,
8889 .doit = hdd_cfg80211_get_station_cmd
8890 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308891 {
8892 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8893 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8894 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308895 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308896 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8897 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308898};
8899
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008900/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308901static const
8902struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008903{
8904#ifdef FEATURE_WLAN_CH_AVOID
8905 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308906 .vendor_id = QCA_NL80211_VENDOR_ID,
8907 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008908 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308909#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8910#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8911 {
8912 /* Index = 1*/
8913 .vendor_id = QCA_NL80211_VENDOR_ID,
8914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8915 },
8916 {
8917 /* Index = 2*/
8918 .vendor_id = QCA_NL80211_VENDOR_ID,
8919 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8920 },
8921 {
8922 /* Index = 3*/
8923 .vendor_id = QCA_NL80211_VENDOR_ID,
8924 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8925 },
8926 {
8927 /* Index = 4*/
8928 .vendor_id = QCA_NL80211_VENDOR_ID,
8929 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8930 },
8931 {
8932 /* Index = 5*/
8933 .vendor_id = QCA_NL80211_VENDOR_ID,
8934 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8935 },
8936 {
8937 /* Index = 6*/
8938 .vendor_id = QCA_NL80211_VENDOR_ID,
8939 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8940 },
8941#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308942#ifdef WLAN_FEATURE_EXTSCAN
8943 {
8944 .vendor_id = QCA_NL80211_VENDOR_ID,
8945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8946 },
8947 {
8948 .vendor_id = QCA_NL80211_VENDOR_ID,
8949 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8950 },
8951 {
8952 .vendor_id = QCA_NL80211_VENDOR_ID,
8953 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8954 },
8955 {
8956 .vendor_id = QCA_NL80211_VENDOR_ID,
8957 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8958 },
8959 {
8960 .vendor_id = QCA_NL80211_VENDOR_ID,
8961 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8962 },
8963 {
8964 .vendor_id = QCA_NL80211_VENDOR_ID,
8965 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8966 },
8967 {
8968 .vendor_id = QCA_NL80211_VENDOR_ID,
8969 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8970 },
8971 {
8972 .vendor_id = QCA_NL80211_VENDOR_ID,
8973 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8974 },
8975 {
8976 .vendor_id = QCA_NL80211_VENDOR_ID,
8977 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8978 },
8979 {
8980 .vendor_id = QCA_NL80211_VENDOR_ID,
8981 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8982 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308983#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308984/*EXT TDLS*/
8985 {
8986 .vendor_id = QCA_NL80211_VENDOR_ID,
8987 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8988 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308989 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8990 .vendor_id = QCA_NL80211_VENDOR_ID,
8991 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8992 },
8993
Srinivas Dasari030bad32015-02-18 23:23:54 +05308994
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308995 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308996 .vendor_id = QCA_NL80211_VENDOR_ID,
8997 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8998 },
8999
Sushant Kaushik084f6592015-09-10 13:11:56 +05309000 {
9001 .vendor_id = QCA_NL80211_VENDOR_ID,
9002 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05309003 },
9004 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
9005 .vendor_id = QCA_NL80211_VENDOR_ID,
9006 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
9007 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05309008 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
9009 .vendor_id = QCA_NL80211_VENDOR_ID,
9010 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
9011 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05309012 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
9013 .vendor_id = QCA_NL80211_VENDOR_ID,
9014 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
9015 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05309016 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
9017 .vendor_id = QCA_NL80211_VENDOR_ID,
9018 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9019 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309020 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9021 .vendor_id = QCA_NL80211_VENDOR_ID,
9022 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9023 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009024};
9025
Jeff Johnson295189b2012-06-20 16:38:30 -07009026/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309027 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309028 * This function is called by hdd_wlan_startup()
9029 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309030 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309032struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009033{
9034 struct wiphy *wiphy;
9035 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309036 /*
9037 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009038 */
9039 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9040
9041 if (!wiphy)
9042 {
9043 /* Print error and jump into err label and free the memory */
9044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9045 return NULL;
9046 }
9047
Sunil Duttc69bccb2014-05-26 21:30:20 +05309048
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 return wiphy;
9050}
9051
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309052#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9053 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9054/**
9055 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9056 * @wiphy: pointer to wiphy
9057 * @config: pointer to config
9058 *
9059 * Return: None
9060 */
9061static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9062 hdd_config_t *config)
9063{
9064 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9065 if (config->max_sched_scan_plan_interval)
9066 wiphy->max_sched_scan_plan_interval =
9067 config->max_sched_scan_plan_interval;
9068 if (config->max_sched_scan_plan_iterations)
9069 wiphy->max_sched_scan_plan_iterations =
9070 config->max_sched_scan_plan_iterations;
9071}
9072#else
9073static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9074 hdd_config_t *config)
9075{
9076}
9077#endif
9078
Jeff Johnson295189b2012-06-20 16:38:30 -07009079/*
9080 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309081 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 * private ioctl to change the band value
9083 */
9084int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9085{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309086 int i, j;
9087 eNVChannelEnabledType channelEnabledState;
9088
Jeff Johnsone7245742012-09-05 17:12:55 -07009089 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309090
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309091 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309093
9094 if (NULL == wiphy->bands[i])
9095 {
9096 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9097 __func__, i);
9098 continue;
9099 }
9100
9101 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9102 {
9103 struct ieee80211_supported_band *band = wiphy->bands[i];
9104
9105 channelEnabledState = vos_nv_getChannelEnabledState(
9106 band->channels[j].hw_value);
9107
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309108 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309109 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309110 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309111 continue;
9112 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309113 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309114 {
9115 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9116 continue;
9117 }
9118
9119 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9120 NV_CHANNEL_INVALID == channelEnabledState)
9121 {
9122 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9123 }
9124 else if (NV_CHANNEL_DFS == channelEnabledState)
9125 {
9126 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9127 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9128 }
9129 else
9130 {
9131 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9132 |IEEE80211_CHAN_RADAR);
9133 }
9134 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009135 }
9136 return 0;
9137}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309138
9139/**
9140 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9141 * @wiphy: Pointer to the wiphy.
9142 *
9143 * This Function adds Channel Switch support flag, if channel switch is
9144 * supported by kernel.
9145 * Return: void.
9146 */
9147#ifdef CHANNEL_SWITCH_SUPPORTED
9148static inline
9149void hdd_add_channel_switch_support(struct wiphy *wiphy)
9150{
9151 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9152 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9153}
9154#else
9155static inline
9156void hdd_add_channel_switch_support(struct wiphy *wiphy)
9157{
9158}
9159#endif
9160
Jeff Johnson295189b2012-06-20 16:38:30 -07009161/*
9162 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309163 * This function is called by hdd_wlan_startup()
9164 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 * This function is used to initialize and register wiphy structure.
9166 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309167int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 struct wiphy *wiphy,
9169 hdd_config_t *pCfg
9170 )
9171{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309172 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309173 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9174
Jeff Johnsone7245742012-09-05 17:12:55 -07009175 ENTER();
9176
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 /* Now bind the underlying wlan device with wiphy */
9178 set_wiphy_dev(wiphy, dev);
9179
9180 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009181
Kiet Lam6c583332013-10-14 05:37:09 +05309182#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009183 /* the flag for the other case would be initialzed in
9184 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9186 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9187#else
Amar Singhal0a402232013-10-11 20:57:16 -07009188 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309189#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309190#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009191
Amar Singhalfddc28c2013-09-05 13:03:40 -07009192 /* This will disable updating of NL channels from passive to
9193 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309194#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9195 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9196#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009197 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309198#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009199
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309200#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9201 wiphy->wowlan = &wowlan_support_cfg80211_init;
9202#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309203 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9204 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309205 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9206 wiphy->wowlan.pattern_min_len = 1;
9207 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9208#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009209
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009211 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9212 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9213 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009214 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309216 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309217#else
9218 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9219#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009220#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009221
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009222#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009223 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009224#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009225 || pCfg->isFastRoamIniFeatureEnabled
9226#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009227#ifdef FEATURE_WLAN_ESE
9228 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009229#endif
9230 )
9231 {
9232 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9233 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009234#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009235#ifdef FEATURE_WLAN_TDLS
9236 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9237 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9238#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309239#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309240 if (pCfg->configPNOScanSupport)
9241 {
9242 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9243 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9244 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9245 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9246 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309247#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009248
Abhishek Singh10d85972015-04-17 10:27:23 +05309249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9250 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9251#endif
9252
Amar Singhalfddc28c2013-09-05 13:03:40 -07009253#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009254 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9255 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009256 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009257 driver need to determine what to do with both
9258 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009259
9260 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009261#else
9262 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009263#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009264
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309265 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9266
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309267 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009268
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309269 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9270
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309272 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9273 | BIT(NL80211_IFTYPE_ADHOC)
9274 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9275 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309276 | BIT(NL80211_IFTYPE_AP)
9277 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009278
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309279 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009280 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309281#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9282 if( pCfg->enableMCC )
9283 {
9284 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309285 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009286
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309287 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309288 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009289
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309290 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309291 wiphy->iface_combinations = wlan_hdd_iface_combination;
9292 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009293#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309294 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 /* Before registering we need to update the ht capabilitied based
9297 * on ini values*/
9298 if( !pCfg->ShortGI20MhzEnable )
9299 {
9300 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9301 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 }
9303
9304 if( !pCfg->ShortGI40MhzEnable )
9305 {
9306 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9307 }
9308
9309 if( !pCfg->nChannelBondingMode5GHz )
9310 {
9311 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9312 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309313 /*
9314 * In case of static linked driver at the time of driver unload,
9315 * module exit doesn't happens. Module cleanup helps in cleaning
9316 * of static memory.
9317 * If driver load happens statically, at the time of driver unload,
9318 * wiphy flags don't get reset because of static memory.
9319 * It's better not to store channel in static memory.
9320 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309321 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9322 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309323 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309324 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309325 {
9326 hddLog(VOS_TRACE_LEVEL_ERROR,
9327 FL("Not enough memory to allocate channels"));
9328 return -ENOMEM;
9329 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309330 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309331 &hdd_channels_2_4_GHZ[0],
9332 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009333
Agrawal Ashish97dec502015-11-26 20:20:58 +05309334 if (true == hdd_is_5g_supported(pHddCtx))
9335 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309336 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9337 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309338 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309339 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309340 {
9341 hddLog(VOS_TRACE_LEVEL_ERROR,
9342 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309343 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9344 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309345 return -ENOMEM;
9346 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309347 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309348 &hdd_channels_5_GHZ[0],
9349 sizeof(hdd_channels_5_GHZ));
9350 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309351
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309352 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309353 {
9354
9355 if (NULL == wiphy->bands[i])
9356 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309357 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309358 __func__, i);
9359 continue;
9360 }
9361
9362 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9363 {
9364 struct ieee80211_supported_band *band = wiphy->bands[i];
9365
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309366 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309367 {
9368 // Enable social channels for P2P
9369 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9370 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9371 else
9372 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9373 continue;
9374 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309375 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309376 {
9377 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9378 continue;
9379 }
9380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 }
9382 /*Initialise the supported cipher suite details*/
9383 wiphy->cipher_suites = hdd_cipher_suites;
9384 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9385
9386 /*signal strength in mBm (100*dBm) */
9387 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9388
9389#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309390 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009391#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009392
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309393 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309394 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9395 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009396 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9397 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9398
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309399 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9400
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309401 EXIT();
9402 return 0;
9403}
9404
9405/* In this function we are registering wiphy. */
9406int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9407{
9408 ENTER();
9409 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 if (0 > wiphy_register(wiphy))
9411 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309412 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9414 return -EIO;
9415 }
9416
9417 EXIT();
9418 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419}
Jeff Johnson295189b2012-06-20 16:38:30 -07009420
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309421/* In this function we are updating channel list when,
9422 regulatory domain is FCC and country code is US.
9423 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9424 As per FCC smart phone is not a indoor device.
9425 GO should not opeate on indoor channels */
9426void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9427{
9428 int j;
9429 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9430 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9431 //Default counrtycode from NV at the time of wiphy initialization.
9432 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9433 &defaultCountryCode[0]))
9434 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009435 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309436 }
9437 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9438 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309439 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309440 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309441 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309442 return;
9443 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309444 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309445 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309446 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309447 // Mark UNII -1 band channel as passive
9448 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9449 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9450 }
9451 }
9452}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309453/* This function registers for all frame which supplicant is interested in */
9454void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009455{
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9457 /* Register for all P2P action, public action etc frames */
9458 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009459 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309460 /* Register frame indication call back */
9461 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 /* Right now we are registering these frame when driver is getting
9463 initialized. Once we will move to 2.6.37 kernel, in which we have
9464 frame register ops, we will move this code as a part of that */
9465 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9468
9469 /* GAS Initial Response */
9470 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9471 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309472
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 /* GAS Comeback Request */
9474 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9475 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9476
9477 /* GAS Comeback Response */
9478 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9479 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9480
9481 /* P2P Public Action */
9482 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309483 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 P2P_PUBLIC_ACTION_FRAME_SIZE );
9485
9486 /* P2P Action */
9487 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9488 (v_U8_t*)P2P_ACTION_FRAME,
9489 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009490
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309491 /* WNM BSS Transition Request frame */
9492 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9493 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9494 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009495
9496 /* WNM-Notification */
9497 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9498 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9499 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009500}
9501
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309502void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009503{
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9505 /* Register for all P2P action, public action etc frames */
9506 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9507
Jeff Johnsone7245742012-09-05 17:12:55 -07009508 ENTER();
9509
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 /* Right now we are registering these frame when driver is getting
9511 initialized. Once we will move to 2.6.37 kernel, in which we have
9512 frame register ops, we will move this code as a part of that */
9513 /* GAS Initial Request */
9514
9515 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9516 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9517
9518 /* GAS Initial Response */
9519 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9520 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309521
Jeff Johnson295189b2012-06-20 16:38:30 -07009522 /* GAS Comeback Request */
9523 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9524 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9525
9526 /* GAS Comeback Response */
9527 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9528 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9529
9530 /* P2P Public Action */
9531 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309532 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 P2P_PUBLIC_ACTION_FRAME_SIZE );
9534
9535 /* P2P Action */
9536 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9537 (v_U8_t*)P2P_ACTION_FRAME,
9538 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009539 /* WNM-Notification */
9540 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9541 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9542 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009543}
9544
9545#ifdef FEATURE_WLAN_WAPI
9546void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309547 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009548{
9549 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9550 tCsrRoamSetKey setKey;
9551 v_BOOL_t isConnected = TRUE;
9552 int status = 0;
9553 v_U32_t roamId= 0xFF;
9554 tANI_U8 *pKeyPtr = NULL;
9555 int n = 0;
9556
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309557 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9558 __func__, hdd_device_modetoString(pAdapter->device_mode),
9559 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009560
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309561 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 setKey.keyId = key_index; // Store Key ID
9563 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9564 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9565 setKey.paeRole = 0 ; // the PAE role
9566 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9567 {
9568 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9569 }
9570 else
9571 {
9572 isConnected = hdd_connIsConnected(pHddStaCtx);
9573 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9574 }
9575 setKey.keyLength = key_Len;
9576 pKeyPtr = setKey.Key;
9577 memcpy( pKeyPtr, key, key_Len);
9578
Arif Hussain6d2a3322013-11-17 19:50:10 -08009579 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 __func__, key_Len);
9581 for (n = 0 ; n < key_Len; n++)
9582 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9583 __func__,n,setKey.Key[n]);
9584
9585 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9586 if ( isConnected )
9587 {
9588 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9589 pAdapter->sessionId, &setKey, &roamId );
9590 }
9591 if ( status != 0 )
9592 {
9593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9594 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9595 __LINE__, status );
9596 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9597 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309598 /* Need to clear any trace of key value in the memory.
9599 * Thus zero out the memory even though it is local
9600 * variable.
9601 */
9602 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009603}
9604#endif /* FEATURE_WLAN_WAPI*/
9605
9606#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 beacon_data_t **ppBeacon,
9609 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009610#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309611int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009612 beacon_data_t **ppBeacon,
9613 struct cfg80211_beacon_data *params,
9614 int dtim_period)
9615#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309616{
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 int size;
9618 beacon_data_t *beacon = NULL;
9619 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309620 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9621 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009622
Jeff Johnsone7245742012-09-05 17:12:55 -07009623 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309625 {
9626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9627 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009630
9631 old = pAdapter->sessionCtx.ap.beacon;
9632
9633 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309634 {
9635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9636 FL("session(%d) old and new heads points to NULL"),
9637 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309639 }
9640
9641 if (params->tail && !params->tail_len)
9642 {
9643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9644 FL("tail_len is zero but tail is not NULL"));
9645 return -EINVAL;
9646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009647
Jeff Johnson295189b2012-06-20 16:38:30 -07009648#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9649 /* Kernel 3.0 is not updating dtim_period for set beacon */
9650 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309651 {
9652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9653 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009656#endif
9657
Kapil Gupta137ef892016-12-13 19:38:00 +05309658 if (params->head)
9659 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309661 head = params->head;
9662 } else
9663 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309665 head = old->head;
9666 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009667
Kapil Gupta137ef892016-12-13 19:38:00 +05309668 if (params->tail || !old)
9669 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309671 tail = params->tail;
9672 } else
9673 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309675 tail = old->tail;
9676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009677
Kapil Gupta137ef892016-12-13 19:38:00 +05309678 if (params->proberesp_ies || !old)
9679 {
9680 proberesp_ies_len = params->proberesp_ies_len;
9681 proberesp_ies = params->proberesp_ies;
9682 } else
9683 {
9684 proberesp_ies_len = old->proberesp_ies_len;
9685 proberesp_ies = old->proberesp_ies;
9686 }
9687
9688 if (params->assocresp_ies || !old)
9689 {
9690 assocresp_ies_len = params->assocresp_ies_len;
9691 assocresp_ies = params->assocresp_ies;
9692 } else
9693 {
9694 assocresp_ies_len = old->assocresp_ies_len;
9695 assocresp_ies = old->assocresp_ies;
9696 }
9697
9698 size = sizeof(beacon_data_t) + head_len + tail_len +
9699 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009700
9701 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309703 {
9704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9705 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009708
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009709#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309710 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 beacon->dtim_period = params->dtim_period;
9712 else
9713 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009714#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309715 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009716 beacon->dtim_period = dtim_period;
9717 else
9718 beacon->dtim_period = old->dtim_period;
9719#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309720
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9722 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309723 beacon->proberesp_ies = beacon->tail + tail_len;
9724 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9725
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 beacon->head_len = head_len;
9727 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309728 beacon->proberesp_ies_len = proberesp_ies_len;
9729 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009730
c_manjee527ecac2017-01-25 12:25:27 +05309731 if (head && head_len)
9732 memcpy(beacon->head, head, head_len);
9733 if (tail && tail_len)
9734 memcpy(beacon->tail, tail, tail_len);
9735 if (proberesp_ies && proberesp_ies_len)
9736 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9737 if (assocresp_ies && assocresp_ies_len)
9738 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009739
9740 *ppBeacon = beacon;
9741
9742 kfree(old);
9743
9744 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009745}
Jeff Johnson295189b2012-06-20 16:38:30 -07009746
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309747v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9749 const v_U8_t *pIes,
9750#else
9751 v_U8_t *pIes,
9752#endif
9753 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009754{
9755 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309756 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309758
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309760 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 elem_id = ptr[0];
9762 elem_len = ptr[1];
9763 left -= 2;
9764 if(elem_len > left)
9765 {
9766 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009767 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 eid,elem_len,left);
9769 return NULL;
9770 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309771 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 {
9773 return ptr;
9774 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309775
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 left -= elem_len;
9777 ptr += (elem_len + 2);
9778 }
9779 return NULL;
9780}
9781
Jeff Johnson295189b2012-06-20 16:38:30 -07009782/* Check if rate is 11g rate or not */
9783static int wlan_hdd_rate_is_11g(u8 rate)
9784{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009785 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 u8 i;
9787 for (i = 0; i < 8; i++)
9788 {
9789 if(rate == gRateArray[i])
9790 return TRUE;
9791 }
9792 return FALSE;
9793}
9794
9795/* Check for 11g rate and set proper 11g only mode */
9796static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9797 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9798{
9799 u8 i, num_rates = pIe[0];
9800
9801 pIe += 1;
9802 for ( i = 0; i < num_rates; i++)
9803 {
9804 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9805 {
9806 /* If rate set have 11g rate than change the mode to 11G */
9807 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9808 if (pIe[i] & BASIC_RATE_MASK)
9809 {
9810 /* If we have 11g rate as basic rate, it means mode
9811 is 11g only mode.
9812 */
9813 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9814 *pCheckRatesfor11g = FALSE;
9815 }
9816 }
9817 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9818 {
9819 *require_ht = TRUE;
9820 }
9821 }
9822 return;
9823}
9824
9825static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9826{
9827 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9828 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9829 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9830 u8 checkRatesfor11g = TRUE;
9831 u8 require_ht = FALSE;
9832 u8 *pIe=NULL;
9833
9834 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9835
9836 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9837 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9838 if (pIe != NULL)
9839 {
9840 pIe += 1;
9841 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9842 &pConfig->SapHw_mode);
9843 }
9844
9845 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9846 WLAN_EID_EXT_SUPP_RATES);
9847 if (pIe != NULL)
9848 {
9849
9850 pIe += 1;
9851 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9852 &pConfig->SapHw_mode);
9853 }
9854
9855 if( pConfig->channel > 14 )
9856 {
9857 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9858 }
9859
9860 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9861 WLAN_EID_HT_CAPABILITY);
9862
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309863 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 {
9865 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9866 if(require_ht)
9867 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9868 }
9869}
9870
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309871static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9872 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9873{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009874 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309875 v_U8_t *pIe = NULL;
9876 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9877
9878 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9879 pBeacon->tail, pBeacon->tail_len);
9880
9881 if (pIe)
9882 {
9883 ielen = pIe[1] + 2;
9884 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9885 {
9886 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9887 }
9888 else
9889 {
9890 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9891 return -EINVAL;
9892 }
9893 *total_ielen += ielen;
9894 }
9895 return 0;
9896}
9897
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009898static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9899 v_U8_t *genie, v_U8_t *total_ielen)
9900{
9901 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9902 int left = pBeacon->tail_len;
9903 v_U8_t *ptr = pBeacon->tail;
9904 v_U8_t elem_id, elem_len;
9905 v_U16_t ielen = 0;
9906
9907 if ( NULL == ptr || 0 == left )
9908 return;
9909
9910 while (left >= 2)
9911 {
9912 elem_id = ptr[0];
9913 elem_len = ptr[1];
9914 left -= 2;
9915 if (elem_len > left)
9916 {
9917 hddLog( VOS_TRACE_LEVEL_ERROR,
9918 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9919 elem_id, elem_len, left);
9920 return;
9921 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309922 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009923 {
9924 /* skipping the VSIE's which we don't want to include or
9925 * it will be included by existing code
9926 */
9927 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9928#ifdef WLAN_FEATURE_WFD
9929 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9930#endif
9931 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9932 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9933 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9934 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9935 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9936 {
9937 ielen = ptr[1] + 2;
9938 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9939 {
9940 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9941 *total_ielen += ielen;
9942 }
9943 else
9944 {
9945 hddLog( VOS_TRACE_LEVEL_ERROR,
9946 "IE Length is too big "
9947 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9948 elem_id, elem_len, *total_ielen);
9949 }
9950 }
9951 }
9952
9953 left -= elem_len;
9954 ptr += (elem_len + 2);
9955 }
9956 return;
9957}
9958
Kapil Gupta137ef892016-12-13 19:38:00 +05309959int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009960{
9961 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309962 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009963 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009964 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309965 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009966
9967 genie = vos_mem_malloc(MAX_GENIE_LEN);
9968
9969 if(genie == NULL) {
9970
9971 return -ENOMEM;
9972 }
9973
Kapil Gupta137ef892016-12-13 19:38:00 +05309974 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309975 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9976 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309978 hddLog(LOGE,
9979 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309980 ret = -EINVAL;
9981 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 }
9983
9984#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309985 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9986 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9987 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309988 hddLog(LOGE,
9989 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309990 ret = -EINVAL;
9991 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009992 }
9993#endif
9994
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309995 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9996 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309998 hddLog(LOGE,
9999 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010000 ret = -EINVAL;
10001 goto done;
10002 }
10003
10004 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
10005 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -070010006 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010008
10009 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10010 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
10011 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10012 {
10013 hddLog(LOGE,
10014 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010015 ret = -EINVAL;
10016 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 }
10018
10019 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10020 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10021 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10022 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10023 ==eHAL_STATUS_FAILURE)
10024 {
10025 hddLog(LOGE,
10026 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010027 ret = -EINVAL;
10028 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 }
10030
10031 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010032 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010034 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 u8 probe_rsp_ie_len[3] = {0};
10036 u8 counter = 0;
10037 /* Check Probe Resp Length if it is greater then 255 then Store
10038 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10039 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10040 Store More then 255 bytes into One Variable.
10041 */
10042 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10043 {
10044 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10045 {
10046 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10047 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10048 }
10049 else
10050 {
10051 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10052 rem_probe_resp_ie_len = 0;
10053 }
10054 }
10055
10056 rem_probe_resp_ie_len = 0;
10057
10058 if (probe_rsp_ie_len[0] > 0)
10059 {
10060 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10061 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010062 (tANI_U8*)&pBeacon->
10063 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 probe_rsp_ie_len[0], NULL,
10065 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10066 {
10067 hddLog(LOGE,
10068 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010069 ret = -EINVAL;
10070 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 }
10072 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10073 }
10074
10075 if (probe_rsp_ie_len[1] > 0)
10076 {
10077 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10078 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010079 (tANI_U8*)&pBeacon->
10080 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 probe_rsp_ie_len[1], NULL,
10082 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10083 {
10084 hddLog(LOGE,
10085 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010086 ret = -EINVAL;
10087 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 }
10089 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10090 }
10091
10092 if (probe_rsp_ie_len[2] > 0)
10093 {
10094 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10095 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010096 (tANI_U8*)&pBeacon->
10097 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 probe_rsp_ie_len[2], NULL,
10099 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10100 {
10101 hddLog(LOGE,
10102 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010103 ret = -EINVAL;
10104 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 }
10106 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10107 }
10108
10109 if (probe_rsp_ie_len[1] == 0 )
10110 {
10111 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10112 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10113 eANI_BOOLEAN_FALSE) )
10114 {
10115 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010116 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010117 }
10118 }
10119
10120 if (probe_rsp_ie_len[2] == 0 )
10121 {
10122 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10123 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10124 eANI_BOOLEAN_FALSE) )
10125 {
10126 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010127 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 }
10129 }
10130
10131 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10132 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10133 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10134 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10135 == eHAL_STATUS_FAILURE)
10136 {
10137 hddLog(LOGE,
10138 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010139 ret = -EINVAL;
10140 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 }
10142 }
10143 else
10144 {
10145 // Reset WNI_CFG_PROBE_RSP Flags
10146 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10147
10148 hddLog(VOS_TRACE_LEVEL_INFO,
10149 "%s: No Probe Response IE received in set beacon",
10150 __func__);
10151 }
10152
10153 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010154 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 {
10156 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010157 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10158 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10160 {
10161 hddLog(LOGE,
10162 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010163 ret = -EINVAL;
10164 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010165 }
10166
10167 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10168 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10169 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10170 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10171 == eHAL_STATUS_FAILURE)
10172 {
10173 hddLog(LOGE,
10174 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010175 ret = -EINVAL;
10176 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 }
10178 }
10179 else
10180 {
10181 hddLog(VOS_TRACE_LEVEL_INFO,
10182 "%s: No Assoc Response IE received in set beacon",
10183 __func__);
10184
10185 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10186 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10187 eANI_BOOLEAN_FALSE) )
10188 {
10189 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010190 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 }
10192 }
10193
Jeff Johnsone7245742012-09-05 17:12:55 -070010194done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010195 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010196 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010197}
Jeff Johnson295189b2012-06-20 16:38:30 -070010198
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010199/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 * FUNCTION: wlan_hdd_validate_operation_channel
10201 * called by wlan_hdd_cfg80211_start_bss() and
10202 * wlan_hdd_cfg80211_set_channel()
10203 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010204 * channel list.
10205 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010206VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010207{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010208
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 v_U32_t num_ch = 0;
10210 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10211 u32 indx = 0;
10212 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010213 v_U8_t fValidChannel = FALSE, count = 0;
10214 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010215
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10217
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010218 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010220 /* Validate the channel */
10221 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010222 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010223 if ( channel == rfChannels[count].channelNum )
10224 {
10225 fValidChannel = TRUE;
10226 break;
10227 }
10228 }
10229 if (fValidChannel != TRUE)
10230 {
10231 hddLog(VOS_TRACE_LEVEL_ERROR,
10232 "%s: Invalid Channel [%d]", __func__, channel);
10233 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010234 }
10235 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010236 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010238 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10239 valid_ch, &num_ch))
10240 {
10241 hddLog(VOS_TRACE_LEVEL_ERROR,
10242 "%s: failed to get valid channel list", __func__);
10243 return VOS_STATUS_E_FAILURE;
10244 }
10245 for (indx = 0; indx < num_ch; indx++)
10246 {
10247 if (channel == valid_ch[indx])
10248 {
10249 break;
10250 }
10251 }
10252
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010253 if (indx >= num_ch)
10254 {
10255 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10256 {
10257 eCsrBand band;
10258 unsigned int freq;
10259
10260 sme_GetFreqBand(hHal, &band);
10261
10262 if (eCSR_BAND_5G == band)
10263 {
10264#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10265 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10266 {
10267 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010268 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010269 }
10270 else
10271 {
10272 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010273 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010274 }
10275#else
10276 freq = ieee80211_channel_to_frequency(channel);
10277#endif
10278 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10279 return VOS_STATUS_SUCCESS;
10280 }
10281 }
10282
10283 hddLog(VOS_TRACE_LEVEL_ERROR,
10284 "%s: Invalid Channel [%d]", __func__, channel);
10285 return VOS_STATUS_E_FAILURE;
10286 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010288
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010290
Jeff Johnson295189b2012-06-20 16:38:30 -070010291}
10292
Viral Modi3a32cc52013-02-08 11:14:52 -080010293/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010294 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010295 * This function is used to set the channel number
10296 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010297static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010298 struct ieee80211_channel *chan,
10299 enum nl80211_channel_type channel_type
10300 )
10301{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010302 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010303 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010304 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010305 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010306 hdd_context_t *pHddCtx;
10307 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010308
10309 ENTER();
10310
10311 if( NULL == dev )
10312 {
10313 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010314 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010315 return -ENODEV;
10316 }
10317 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010318
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010319 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10320 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10321 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010322 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010323 "%s: device_mode = %s (%d) freq = %d", __func__,
10324 hdd_device_modetoString(pAdapter->device_mode),
10325 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010326
10327 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10328 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010329 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010330 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010331 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010332 }
10333
10334 /*
10335 * Do freq to chan conversion
10336 * TODO: for 11a
10337 */
10338
10339 channel = ieee80211_frequency_to_channel(freq);
10340
10341 /* Check freq range */
10342 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10343 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10344 {
10345 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010346 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010347 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10348 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10349 return -EINVAL;
10350 }
10351
10352 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10353
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010354 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10355 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010356 {
10357 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10358 {
10359 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010360 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010361 return -EINVAL;
10362 }
10363 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10364 "%s: set channel to [%d] for device mode =%d",
10365 __func__, channel,pAdapter->device_mode);
10366 }
10367 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010368 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010369 )
10370 {
10371 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10372 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10373 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10374
10375 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10376 {
10377 /* Link is up then return cant set channel*/
10378 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010379 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010380 return -EINVAL;
10381 }
10382
10383 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10384 pHddStaCtx->conn_info.operationChannel = channel;
10385 pRoamProfile->ChannelInfo.ChannelList =
10386 &pHddStaCtx->conn_info.operationChannel;
10387 }
10388 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010389 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010390 )
10391 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010392 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10393 {
10394 if(VOS_STATUS_SUCCESS !=
10395 wlan_hdd_validate_operation_channel(pAdapter,channel))
10396 {
10397 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010398 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010399 return -EINVAL;
10400 }
10401 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10402 }
10403 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010404 {
10405 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10406
10407 /* If auto channel selection is configured as enable/ 1 then ignore
10408 channel set by supplicant
10409 */
10410 if ( cfg_param->apAutoChannelSelection )
10411 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010412 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10413 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010414 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010415 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10416 __func__, hdd_device_modetoString(pAdapter->device_mode),
10417 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010418 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010419 else
10420 {
10421 if(VOS_STATUS_SUCCESS !=
10422 wlan_hdd_validate_operation_channel(pAdapter,channel))
10423 {
10424 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010425 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010426 return -EINVAL;
10427 }
10428 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10429 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010430 }
10431 }
10432 else
10433 {
10434 hddLog(VOS_TRACE_LEVEL_FATAL,
10435 "%s: Invalid device mode failed to set valid channel", __func__);
10436 return -EINVAL;
10437 }
10438 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010439 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010440}
10441
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010442static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10443 struct net_device *dev,
10444 struct ieee80211_channel *chan,
10445 enum nl80211_channel_type channel_type
10446 )
10447{
10448 int ret;
10449
10450 vos_ssr_protect(__func__);
10451 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10452 vos_ssr_unprotect(__func__);
10453
10454 return ret;
10455}
10456
Anurag Chouhan83026002016-12-13 22:46:21 +053010457#ifdef DHCP_SERVER_OFFLOAD
10458void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10459 VOS_STATUS status)
10460{
10461 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10462
10463 ENTER();
10464
10465 if (NULL == adapter)
10466 {
10467 hddLog(VOS_TRACE_LEVEL_ERROR,
10468 "%s: adapter is NULL",__func__);
10469 return;
10470 }
10471
10472 adapter->dhcp_status.dhcp_offload_status = status;
10473 vos_event_set(&adapter->dhcp_status.vos_event);
10474 return;
10475}
10476
10477/**
10478 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10479 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010480 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010481 *
10482 * Return: None
10483 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010484VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10485 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010486{
10487 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10488 sir_dhcp_srv_offload_info dhcp_srv_info;
10489 tANI_U8 num_entries = 0;
10490 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10491 tANI_U8 num;
10492 tANI_U32 temp;
10493 VOS_STATUS ret;
10494
10495 ENTER();
10496
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010497 if (!re_init) {
10498 ret = wlan_hdd_validate_context(hdd_ctx);
10499 if (0 != ret)
10500 return VOS_STATUS_E_INVAL;
10501 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010502
10503 /* Prepare the request to send to SME */
10504 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10505 if (NULL == dhcp_srv_info) {
10506 hddLog(VOS_TRACE_LEVEL_ERROR,
10507 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10508 return VOS_STATUS_E_NOMEM;
10509 }
10510
10511 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10512
10513 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10514 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10515 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10516 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10517 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10518 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10519
10520 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10521 srv_ip,
10522 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010523 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010524 if (num_entries != IPADDR_NUM_ENTRIES) {
10525 hddLog(VOS_TRACE_LEVEL_ERROR,
10526 "%s: incorrect IP address (%s) assigned for DHCP server!",
10527 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10528 vos_mem_free(dhcp_srv_info);
10529 return VOS_STATUS_E_FAILURE;
10530 }
10531
10532 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10533 hddLog(VOS_TRACE_LEVEL_ERROR,
10534 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10535 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10536 vos_mem_free(dhcp_srv_info);
10537 return VOS_STATUS_E_FAILURE;
10538 }
10539
10540 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10541 hddLog(VOS_TRACE_LEVEL_ERROR,
10542 "%s: invalid IP address (%s)! The last field must be less than 100!",
10543 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10544 vos_mem_free(dhcp_srv_info);
10545 return VOS_STATUS_E_FAILURE;
10546 }
10547
10548 for (num = 0; num < num_entries; num++) {
10549 temp = srv_ip[num];
10550 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10551 }
10552
10553 if (eHAL_STATUS_SUCCESS !=
10554 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10555 hddLog(VOS_TRACE_LEVEL_ERROR,
10556 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10557 vos_mem_free(dhcp_srv_info);
10558 return VOS_STATUS_E_FAILURE;
10559 }
10560
10561 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10562 "%s: enable DHCP Server offload successfully!", __func__);
10563
10564 vos_mem_free(dhcp_srv_info);
10565 return 0;
10566}
10567#endif /* DHCP_SERVER_OFFLOAD */
10568
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010569/*
10570 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10571 * @wiphy_chan: wiphy channel number
10572 * @rfChannel: channel hw value
10573 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010574 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010575 *
10576 * Modify wiphy flags and cds state if channel is indoor.
10577 *
10578 * Return: void
10579 */
10580void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010581 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010582{
10583 v_U32_t channelLoop;
10584 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10585
10586 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10587
10588 if (rfChannels[channelLoop].channelNum == rfChannel) {
10589 channelEnum = (eRfChannels)channelLoop;
10590 break;
10591 }
10592 }
10593
10594 if (INVALID_RF_CHANNEL == channelEnum)
10595 return;
10596
10597 if (disable) {
10598 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10599 wiphy_chan->flags |=
10600 IEEE80211_CHAN_DISABLED;
10601 regChannels[channelEnum].enabled =
10602 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010603 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10604 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010605 }
10606 } else {
10607 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10608 wiphy_chan->flags &=
10609 ~IEEE80211_CHAN_DISABLED;
10610 /*
10611 * Indoor channels are marked as DFS
10612 * during regulatory processing
10613 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010614 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10615 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10616 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10617 && (wiphy_chan->flags &
10618 IEEE80211_CHAN_INDOOR_ONLY))) {
10619 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10620 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10621 channelEnum);
10622 } else {
10623 regChannels[channelEnum].enabled =
10624 NV_CHANNEL_ENABLE;
10625 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10626 channelEnum);
10627 }
10628 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010629
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010630 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010631}
10632
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010633void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010634{
10635 int band_num;
10636 int chan_num;
10637 v_U32_t rfChannel;
10638 struct ieee80211_channel *wiphy_chan;
10639 struct wiphy *wiphy;
10640
10641 ENTER();
10642 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10643
10644 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010645 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010646
10647 if (wiphy->bands[band_num] == NULL)
10648 continue;
10649
10650 for (chan_num = 0;
10651 chan_num < wiphy->bands[band_num]->n_channels;
10652 chan_num++) {
10653
10654 wiphy_chan =
10655 &(wiphy->bands[band_num]->channels[chan_num]);
10656 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10657
10658 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010659 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010660 }
10661 }
10662 EXIT();
10663}
10664
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010665int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10666{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010667 eHalStatus status;
10668 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010669 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10670 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10671 long ret;
10672 eConnectionState prev_conn_state;
10673 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10674
10675 ENTER();
10676
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010677 /* Indicate sme of disconnect so that in progress connection or preauth
10678 * can be aborted
10679 */
10680 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10681 pAdapter->sessionId);
10682 pHddCtx->isAmpAllowed = VOS_TRUE;
10683
10684 /* Need to apply spin lock before decreasing active sessions
10685 * as there can be chance for double decrement if context switch
10686 * Calls hdd_DisConnectHandler.
10687 */
10688
10689 prev_conn_state = pHddStaCtx->conn_info.connState;
10690
10691 spin_lock_bh(&pAdapter->lock_for_active_session);
10692 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10693 {
10694 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10695 }
10696 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10697 spin_unlock_bh(&pAdapter->lock_for_active_session);
10698 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10699
10700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10701 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10702
10703 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10704
10705 /*
10706 * stop tx queues before deleting STA/BSS context from the firmware.
10707 * tx has to be disabled because the firmware can get busy dropping
10708 * the tx frames after BSS/STA has been deleted and will not send
10709 * back a response resulting in WDI timeout
10710 */
10711 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10712 netif_tx_disable(pAdapter->dev);
10713 netif_carrier_off(pAdapter->dev);
10714
10715 wlan_hdd_check_and_stop_mon(pAdapter, true);
10716
10717 /*issue disconnect*/
10718 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10719 pAdapter->sessionId, reason);
10720 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10721 prev_conn_state != eConnectionState_Connecting)
10722 {
10723 hddLog(LOG1,
10724 FL("status = %d, already disconnected"), status);
10725 result = 0;
10726 /*
10727 * Wait here instead of returning directly. This will block the
10728 * next connect command and allow processing of the disconnect
10729 * in SME else we might hit some race conditions leading to SME
10730 * and HDD out of sync. As disconnect is already in progress,
10731 * wait here for 1 sec instead of 5 sec.
10732 */
10733 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10734 goto wait_for_disconnect;
10735 }
10736 /*
10737 * Wait here instead of returning directly, this will block the next
10738 * connect command and allow processing of the scan for ssid and
10739 * the previous connect command in CSR. Else we might hit some
10740 * race conditions leading to SME and HDD out of sync.
10741 */
10742 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10743 {
10744 hddLog(LOG1,
10745 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10746 }
10747 else if ( 0 != status )
10748 {
10749 hddLog(LOGE,
10750 FL("csrRoamDisconnect failure, returned %d"),
10751 (int)status);
10752 result = -EINVAL;
10753 goto disconnected;
10754 }
10755wait_for_disconnect:
10756 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10757 msecs_to_jiffies(wait_time));
10758 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10759 {
10760 hddLog(LOGE,
10761 "%s: Failed to disconnect, timed out", __func__);
10762 result = -ETIMEDOUT;
10763 }
10764disconnected:
10765 hddLog(LOG1,
10766 FL("Set HDD connState to eConnectionState_NotConnected"));
10767 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10768#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10769 /* Sending disconnect event to userspace for kernel version < 3.11
10770 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10771 */
10772 hddLog(LOG1, FL("Send disconnected event to userspace"));
10773
10774 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10775 WLAN_REASON_UNSPECIFIED);
10776#endif
10777
10778 EXIT();
10779 return result;
10780}
10781
10782/*
10783 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10784 * on indoor channel
10785 * @hdd_ctx: pointer to hdd context
10786 *
10787 * STA should be disconnected before starting the SAP if it is on indoor
10788 * channel.
10789 *
10790 * Return: void
10791 */
10792void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10793{
10794
10795 hdd_adapter_t *sta_adapter;
10796 tANI_U8 sta_chan;
10797
10798 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10799
10800 if (!sta_chan) {
10801 hddLog(LOG1, FL("STA not connected"));
10802 return;
10803 }
10804
10805 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10806
10807 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10808 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10809 sta_chan);
10810 return;
10811 }
10812
10813 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10814
10815 if (!sta_adapter) {
10816 hddLog(LOG1, FL("STA adapter doesn't exist"));
10817 return;
10818 }
10819
10820 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10821 /* Issue Disconnect request */
10822 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10823}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010824
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010825int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10826{
10827 struct hdd_cache_channels *cache_chann;
10828 struct wiphy *wiphy;
10829 int freq, status, rfChannel;
10830 int i, band_num, channel_num;
10831 struct ieee80211_channel *wiphy_channel;
10832
10833 ENTER();
10834
10835 if (!hdd_ctx) {
10836 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10837 return -EINVAL;
10838 }
10839
10840 wiphy = hdd_ctx->wiphy;
10841
10842 mutex_lock(&hdd_ctx->cache_channel_lock);
10843
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010844 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010845
10846 if (!cache_chann || !cache_chann->num_channels) {
10847 hddLog(VOS_TRACE_LEVEL_INFO,
10848 "%s channel list is NULL or num channels are zero",
10849 __func__);
10850 mutex_unlock(&hdd_ctx->cache_channel_lock);
10851 return -EINVAL;
10852 }
10853
10854 for (i = 0; i < cache_chann->num_channels; i++) {
10855 status = hdd_wlan_get_freq(
10856 cache_chann->channel_info[i].channel_num,
10857 &freq);
10858
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010859 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10860 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010861 if (!wiphy->bands[band_num])
10862 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010863 for (channel_num = 0; channel_num <
10864 wiphy->bands[band_num]->n_channels;
10865 channel_num++) {
10866 wiphy_channel = &(wiphy->bands[band_num]->
10867 channels[channel_num]);
10868 if (wiphy_channel->center_freq == freq) {
10869 rfChannel = wiphy_channel->hw_value;
10870 /*
10871 *Restore the orginal states
10872 *of the channels
10873 */
10874 vos_nv_set_channel_state(
10875 rfChannel,
10876 cache_chann->
10877 channel_info[i].reg_status);
10878 wiphy_channel->flags =
10879 cache_chann->
10880 channel_info[i].wiphy_status;
10881 break;
10882 }
10883 }
10884 if (channel_num < wiphy->bands[band_num]->n_channels)
10885 break;
10886 }
10887 }
10888
10889 mutex_unlock(&hdd_ctx->cache_channel_lock);
10890
10891 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10892 if (status)
10893 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10894 EXIT();
10895
10896 return 0;
10897}
10898
10899/*
10900 * wlan_hdd_disable_channels() - Cache the the channels
10901 * and current state of the channels from the channel list
10902 * received in the command and disable the channels on the
10903 * wiphy and NV table.
10904 * @hdd_ctx: Pointer to hdd context
10905 *
10906 * @return: 0 on success, Error code on failure
10907 */
10908
10909static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10910{
10911 struct hdd_cache_channels *cache_chann;
10912 struct wiphy *wiphy;
10913 int freq, status, rfChannel;
10914 int i, band_num, band_ch_num;
10915 struct ieee80211_channel *wiphy_channel;
10916
10917 if (!hdd_ctx) {
10918 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10919 return -EINVAL;
10920 }
10921
10922 wiphy = hdd_ctx->wiphy;
10923
10924 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010925 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010926
10927 if (!cache_chann || !cache_chann->num_channels) {
10928 hddLog(VOS_TRACE_LEVEL_INFO,
10929 "%s channel list is NULL or num channels are zero",
10930 __func__);
10931 mutex_unlock(&hdd_ctx->cache_channel_lock);
10932 return -EINVAL;
10933 }
10934
10935 for (i = 0; i < cache_chann->num_channels; i++) {
10936 status = hdd_wlan_get_freq(
10937 cache_chann->channel_info[i].channel_num,
10938 &freq);
10939
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010940 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010941 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010942 if (!wiphy->bands[band_num])
10943 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010944 for (band_ch_num = 0; band_ch_num <
10945 wiphy->bands[band_num]->n_channels;
10946 band_ch_num++) {
10947 wiphy_channel = &(wiphy->bands[band_num]->
10948 channels[band_ch_num]);
10949 if (wiphy_channel->center_freq == freq) {
10950 rfChannel = wiphy_channel->hw_value;
10951 /*
10952 * Cache the current states of
10953 * the channels
10954 */
10955 cache_chann->
10956 channel_info[i].reg_status =
10957 vos_nv_getChannelEnabledState(
10958 rfChannel);
10959
10960 cache_chann->
10961 channel_info[i].wiphy_status =
10962 wiphy_channel->flags;
10963 hddLog(VOS_TRACE_LEVEL_INFO,
10964 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10965 cache_chann->
10966 channel_info[i].channel_num,
10967 cache_chann->
10968 channel_info[i].reg_status,
10969 wiphy_channel->flags);
10970
10971 vos_nv_set_channel_state(
10972 rfChannel,
10973 NV_CHANNEL_DISABLE);
10974 wiphy_channel->flags |=
10975 IEEE80211_CHAN_DISABLED;
10976 break;
10977 }
10978 }
10979 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10980 break;
10981 }
10982 }
10983
10984 mutex_unlock(&hdd_ctx->cache_channel_lock);
10985 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10986 return 0;
10987}
10988
Jeff Johnson295189b2012-06-20 16:38:30 -070010989#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10990static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10991 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010992#else
10993static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10994 struct cfg80211_beacon_data *params,
10995 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010996 enum nl80211_hidden_ssid hidden_ssid,
10997 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010999{
11000 tsap_Config_t *pConfig;
11001 beacon_data_t *pBeacon = NULL;
11002 struct ieee80211_mgmt *pMgmt_frame;
11003 v_U8_t *pIe=NULL;
11004 v_U16_t capab_info;
11005 eCsrAuthType RSNAuthType;
11006 eCsrEncryptionType RSNEncryptType;
11007 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011008 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 tpWLAN_SAPEventCB pSapEventCallback;
11010 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011012 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011014 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080011016 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011017 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053011018 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070011019 v_BOOL_t MFPCapable = VOS_FALSE;
11020 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011021 v_BOOL_t sapEnable11AC =
11022 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053011023 u_int16_t prev_rsn_length = 0;
11024
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 ENTER();
11026
Nitesh Shah9b066282017-06-06 18:05:52 +053011027 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011028
11029 /*
11030 * For STA+SAP concurrency support from GUI, first STA connection gets
11031 * triggered and while it is in progress, SAP start also comes up.
11032 * Once STA association is successful, STA connect event is sent to
11033 * kernel which gets queued in kernel workqueue and supplicant won't
11034 * process M1 received from AP and send M2 until this NL80211_CONNECT
11035 * event is received. Workqueue is not scheduled as RTNL lock is already
11036 * taken by hostapd thread which has issued start_bss command to driver.
11037 * Driver cannot complete start_bss as the pending command at the head
11038 * of the SME command pending list is hw_mode_update for STA session
11039 * which cannot be processed as SME is in WAITforKey state for STA
11040 * interface. The start_bss command for SAP interface is queued behind
11041 * the hw_mode_update command and so it cannot be processed until
11042 * hw_mode_update command is processed. This is causing a deadlock so
11043 * disconnect the STA interface first if connection or key exchange is
11044 * in progress and then start SAP interface.
11045 */
11046 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11047 if (sta_adapter) {
11048 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11049 sta_adapter->sessionId);
11050 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11051 }
11052
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011053 iniConfig = pHddCtx->cfg_ini;
11054
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011055 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011056 if (iniConfig->disable_indoor_channel &&
11057 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011058 hdd_update_indoor_channel(pHddCtx, true);
11059
11060 if (!VOS_IS_STATUS_SUCCESS(
11061 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11062 hdd_update_indoor_channel(pHddCtx, false);
11063 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11064 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011065 ret = eHAL_STATUS_FAILURE;
11066 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011067 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011068
11069 /* check if STA is on indoor channel */
11070 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11071 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011072 }
11073
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011074 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
11075 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
11076 wlan_hdd_disable_channels(pHddCtx);
11077 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
11078 }
11079
Jeff Johnson295189b2012-06-20 16:38:30 -070011080 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11081
11082 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11083
11084 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11085
11086 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11087
11088 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11089
11090 //channel is already set in the set_channel Call back
11091 //pConfig->channel = pCommitConfig->channel;
11092
11093 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011094 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11096
11097 pConfig->dtim_period = pBeacon->dtim_period;
11098
Arif Hussain6d2a3322013-11-17 19:50:10 -080011099 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011100 pConfig->dtim_period);
11101
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011102 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011103 {
11104 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011106 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11107 {
11108 tANI_BOOLEAN restartNeeded;
11109 pConfig->ieee80211d = 1;
11110 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11111 sme_setRegInfo(hHal, pConfig->countryCode);
11112 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11113 }
11114 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011116 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011117 pConfig->ieee80211d = 1;
11118 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11119 sme_setRegInfo(hHal, pConfig->countryCode);
11120 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011122 else
11123 {
11124 pConfig->ieee80211d = 0;
11125 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011126 /*
11127 * If auto channel is configured i.e. channel is 0,
11128 * so skip channel validation.
11129 */
11130 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11131 {
11132 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11133 {
11134 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011135 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011136 ret = -EINVAL;
11137 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011138 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011139 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011140 }
11141 else
11142 {
11143 if(1 != pHddCtx->is_dynamic_channel_range_set)
11144 {
11145 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11146 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11147 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11148 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011149 pHddCtx->is_dynamic_channel_range_set = 0;
11150 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011151 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011153 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 {
11155 pConfig->ieee80211d = 0;
11156 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011157
11158#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11159 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11160 pConfig->authType = eSAP_OPEN_SYSTEM;
11161 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11162 pConfig->authType = eSAP_SHARED_KEY;
11163 else
11164 pConfig->authType = eSAP_AUTO_SWITCH;
11165#else
11166 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11167 pConfig->authType = eSAP_OPEN_SYSTEM;
11168 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11169 pConfig->authType = eSAP_SHARED_KEY;
11170 else
11171 pConfig->authType = eSAP_AUTO_SWITCH;
11172#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011173
11174 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011175
11176 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011178#ifdef SAP_AUTH_OFFLOAD
11179 /* In case of sap offload, hostapd.conf is configuted with open mode and
11180 * security is configured from ini file. Due to open mode in hostapd.conf
11181 * privacy bit is set to false which will result in not sending,
11182 * data packets as encrypted.
11183 * If enable_sap_auth_offload is enabled in ini and
11184 * sap_auth_offload_sec_type is type of WPA2-PSK,
11185 * driver will set privacy bit to 1.
11186 */
11187 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11188 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11189 pConfig->privacy = VOS_TRUE;
11190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011191
11192 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11193
11194 /*Set wps station to configured*/
11195 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11196
11197 if(pIe)
11198 {
11199 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11200 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011201 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011202 ret = -EINVAL;
11203 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 }
11205 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11206 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011207 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011208 /* Check 15 bit of WPS IE as it contain information for wps state
11209 * WPS state
11210 */
11211 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11212 {
11213 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11214 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11215 {
11216 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11217 }
11218 }
11219 }
11220 else
11221 {
11222 pConfig->wps_state = SAP_WPS_DISABLED;
11223 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011225
c_hpothufe599e92014-06-16 11:38:55 +053011226 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11227 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11228 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11229 eCSR_ENCRYPT_TYPE_NONE;
11230
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011232 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011233 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 WLAN_EID_RSN);
11235 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011236 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011238 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11239 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11240 pConfig->RSNWPAReqIELength);
11241 else
11242 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11243 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011244 /* The actual processing may eventually be more extensive than
11245 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 * by the app.
11247 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011248 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11250 &RSNEncryptType,
11251 &mcRSNEncryptType,
11252 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011253 &MFPCapable,
11254 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011255 pConfig->RSNWPAReqIE[1]+2,
11256 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011257
11258 if( VOS_STATUS_SUCCESS == status )
11259 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011260 /* Now copy over all the security attributes you have
11261 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 * */
11263 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11264 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11265 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11266 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011267 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011268 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11270 }
11271 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011272
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11274 pBeacon->tail, pBeacon->tail_len);
11275
11276 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11277 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011278 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 {
11280 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011281 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011283 if (pConfig->RSNWPAReqIELength <=
11284 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11285 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11286 pIe[1] + 2);
11287 else
11288 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11289 pConfig->RSNWPAReqIELength);
11290
Jeff Johnson295189b2012-06-20 16:38:30 -070011291 }
11292 else
11293 {
11294 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011295 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11296 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11297 pConfig->RSNWPAReqIELength);
11298 else
11299 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11300 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011301 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11303 &RSNEncryptType,
11304 &mcRSNEncryptType,
11305 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011306 &MFPCapable,
11307 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011308 pConfig->RSNWPAReqIE[1]+2,
11309 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011310
11311 if( VOS_STATUS_SUCCESS == status )
11312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011313 /* Now copy over all the security attributes you have
11314 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 * */
11316 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11317 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11318 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11319 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011320 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011321 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11323 }
11324 }
11325 }
11326
Kapil Gupta137ef892016-12-13 19:38:00 +053011327 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011328 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011329 ret = -EINVAL;
11330 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011331 }
11332
Jeff Johnson295189b2012-06-20 16:38:30 -070011333 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11334
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011335#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 if (params->ssid != NULL)
11337 {
11338 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11339 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11340 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11341 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11342 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011343#else
11344 if (ssid != NULL)
11345 {
11346 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11347 pConfig->SSIDinfo.ssid.length = ssid_len;
11348 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11349 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11350 }
11351#endif
11352
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011353 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011355
Jeff Johnson295189b2012-06-20 16:38:30 -070011356 /* default value */
11357 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11358 pConfig->num_accept_mac = 0;
11359 pConfig->num_deny_mac = 0;
11360
11361 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11362 pBeacon->tail, pBeacon->tail_len);
11363
11364 /* pIe for black list is following form:
11365 type : 1 byte
11366 length : 1 byte
11367 OUI : 4 bytes
11368 acl type : 1 byte
11369 no of mac addr in black list: 1 byte
11370 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011371 */
11372 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 {
11374 pConfig->SapMacaddr_acl = pIe[6];
11375 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011376 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011378 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11379 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11381 for (i = 0; i < pConfig->num_deny_mac; i++)
11382 {
11383 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11384 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 }
11387 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11388 pBeacon->tail, pBeacon->tail_len);
11389
11390 /* pIe for white list is following form:
11391 type : 1 byte
11392 length : 1 byte
11393 OUI : 4 bytes
11394 acl type : 1 byte
11395 no of mac addr in white list: 1 byte
11396 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011397 */
11398 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 {
11400 pConfig->SapMacaddr_acl = pIe[6];
11401 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011402 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011403 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011404 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11405 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11407 for (i = 0; i < pConfig->num_accept_mac; i++)
11408 {
11409 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11410 acl_entry++;
11411 }
11412 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011413
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11415
Jeff Johnsone7245742012-09-05 17:12:55 -070011416#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011417 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011418 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11419 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011420 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11421 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011422 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11423 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011424 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11425 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011426 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011427 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011428 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011429 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011430
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011431 /* If ACS disable and selected channel <= 14
11432 * OR
11433 * ACS enabled and ACS operating band is choosen as 2.4
11434 * AND
11435 * VHT in 2.4G Disabled
11436 * THEN
11437 * Fallback to 11N mode
11438 */
11439 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11440 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011441 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011442 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011443 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011444 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11445 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011446 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11447 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011448 }
11449#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011450
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 // ht_capab is not what the name conveys,this is used for protection bitmap
11452 pConfig->ht_capab =
11453 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11454
Kapil Gupta137ef892016-12-13 19:38:00 +053011455 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 {
11457 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011458 ret = -EINVAL;
11459 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 }
11461
11462 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11465 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466 pConfig->obssProtEnabled =
11467 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011468
Chet Lanctot8cecea22014-02-11 19:09:36 -080011469#ifdef WLAN_FEATURE_11W
11470 pConfig->mfpCapable = MFPCapable;
11471 pConfig->mfpRequired = MFPRequired;
11472 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11473 pConfig->mfpCapable, pConfig->mfpRequired);
11474#endif
11475
Arif Hussain6d2a3322013-11-17 19:50:10 -080011476 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011478 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11479 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11480 (int)pConfig->channel);
11481 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11482 pConfig->SapHw_mode, pConfig->privacy,
11483 pConfig->authType);
11484 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11485 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11486 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11487 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011488
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011489 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 {
11491 //Bss already started. just return.
11492 //TODO Probably it should update some beacon params.
11493 hddLog( LOGE, "Bss Already started...Ignore the request");
11494 EXIT();
11495 return 0;
11496 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011497
Agarwal Ashish51325b52014-06-16 16:50:49 +053011498 if (vos_max_concurrent_connections_reached()) {
11499 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011500 ret = -EINVAL;
11501 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011502 }
11503
Jeff Johnson295189b2012-06-20 16:38:30 -070011504 pConfig->persona = pHostapdAdapter->device_mode;
11505
Peng Xu2446a892014-09-05 17:21:18 +053011506 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11507 if ( NULL != psmeConfig)
11508 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011509 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011510 sme_GetConfigParam(hHal, psmeConfig);
11511 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011512#ifdef WLAN_FEATURE_AP_HT40_24G
11513 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11514 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11515 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11516 {
11517 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11518 sme_UpdateConfig (hHal, psmeConfig);
11519 }
11520#endif
Peng Xu2446a892014-09-05 17:21:18 +053011521 vos_mem_free(psmeConfig);
11522 }
Peng Xuafc34e32014-09-25 13:23:55 +053011523 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011524
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011525 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011527
11528 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11530 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11531 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011532 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011533 ret = -EINVAL;
11534 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 }
11536
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011537 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11539
11540 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011541
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011543 {
11544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011545 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011546 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011547 VOS_ASSERT(0);
11548 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011549
Jeff Johnson295189b2012-06-20 16:38:30 -070011550 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011551 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11552 VOS_STATUS_SUCCESS)
11553 {
11554 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11555 VOS_ASSERT(0);
11556 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011557 /* Initialize WMM configuation */
11558 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011559 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011560
Anurag Chouhan83026002016-12-13 22:46:21 +053011561#ifdef DHCP_SERVER_OFFLOAD
11562 /* set dhcp server offload */
11563 if (iniConfig->enable_dhcp_srv_offload &&
11564 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011565 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011566 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011567 if (!VOS_IS_STATUS_SUCCESS(status))
11568 {
11569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11570 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011571 vos_event_reset(&pHostapdState->vosEvent);
11572 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11573 status = vos_wait_single_event(&pHostapdState->vosEvent,
11574 10000);
11575 if (!VOS_IS_STATUS_SUCCESS(status)) {
11576 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011577 ret = -EINVAL;
11578 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011579 }
11580 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011581 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011582 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11583 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11584 {
11585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11586 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11587 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011588 vos_event_reset(&pHostapdState->vosEvent);
11589 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11590 status = vos_wait_single_event(&pHostapdState->vosEvent,
11591 10000);
11592 if (!VOS_IS_STATUS_SUCCESS(status)) {
11593 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011594 ret = -EINVAL;
11595 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011596 }
11597 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011598 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011599#ifdef MDNS_OFFLOAD
11600 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011601 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011602 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11603 if (VOS_IS_STATUS_SUCCESS(status))
11604 {
11605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11606 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011607 vos_event_reset(&pHostapdState->vosEvent);
11608 if (VOS_STATUS_SUCCESS ==
11609 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11610 status = vos_wait_single_event(&pHostapdState->vosEvent,
11611 10000);
11612 if (!VOS_IS_STATUS_SUCCESS(status)) {
11613 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011614 ret = -EINVAL;
11615 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011616 }
11617 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011618 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011619 status = vos_wait_single_event(&pHostapdAdapter->
11620 mdns_status.vos_event, 2000);
11621 if (!VOS_IS_STATUS_SUCCESS(status) ||
11622 pHostapdAdapter->mdns_status.mdns_enable_status ||
11623 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11624 pHostapdAdapter->mdns_status.mdns_resp_status)
11625 {
11626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11627 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11628 pHostapdAdapter->mdns_status.mdns_enable_status,
11629 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11630 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011631 vos_event_reset(&pHostapdState->vosEvent);
11632 if (VOS_STATUS_SUCCESS ==
11633 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11634 status = vos_wait_single_event(&pHostapdState->vosEvent,
11635 10000);
11636 if (!VOS_IS_STATUS_SUCCESS(status)) {
11637 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011638 ret = -EINVAL;
11639 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011640 }
11641 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011642 }
11643 }
11644#endif /* MDNS_OFFLOAD */
11645 } else {
11646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11647 ("DHCP Disabled ini %d, FW %d"),
11648 iniConfig->enable_dhcp_srv_offload,
11649 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011650 }
11651#endif /* DHCP_SERVER_OFFLOAD */
11652
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011653#ifdef WLAN_FEATURE_P2P_DEBUG
11654 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11655 {
11656 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11657 {
11658 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11659 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011660 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011661 }
11662 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11663 {
11664 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11665 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011666 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011667 }
11668 }
11669#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011670 /* Check and restart SAP if it is on Unsafe channel */
11671 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011672
Jeff Johnson295189b2012-06-20 16:38:30 -070011673 pHostapdState->bCommit = TRUE;
11674 EXIT();
11675
11676 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011677error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011678 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11679 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011680 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011681 if (iniConfig->disable_indoor_channel &&
11682 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011683 hdd_update_indoor_channel(pHddCtx, false);
11684 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11685 }
11686
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011687 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011688
11689tdls_enable:
11690 if (ret != eHAL_STATUS_SUCCESS)
11691 wlan_hdd_tdls_reenable(pHddCtx);
11692
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011693 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011694}
11695
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011696#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011697static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 struct beacon_parameters *params)
11700{
11701 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011702 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011703 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011704
11705 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011706
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11708 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11709 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011710 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11711 hdd_device_modetoString(pAdapter->device_mode),
11712 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011713
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011714 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11715 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011716 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011718 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011719 }
11720
Agarwal Ashish51325b52014-06-16 16:50:49 +053011721 if (vos_max_concurrent_connections_reached()) {
11722 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11723 return -EINVAL;
11724 }
11725
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011726 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011728 )
11729 {
11730 beacon_data_t *old,*new;
11731
11732 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011733
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011735 {
11736 hddLog(VOS_TRACE_LEVEL_WARN,
11737 FL("already beacon info added to session(%d)"),
11738 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011740 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011741
11742 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11743
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 {
11746 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011747 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 return -EINVAL;
11749 }
11750
11751 pAdapter->sessionCtx.ap.beacon = new;
11752
11753 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11754 }
11755
11756 EXIT();
11757 return status;
11758}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011759
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011760static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11761 struct net_device *dev,
11762 struct beacon_parameters *params)
11763{
11764 int ret;
11765
11766 vos_ssr_protect(__func__);
11767 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11768 vos_ssr_unprotect(__func__);
11769
11770 return ret;
11771}
11772
11773static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 struct net_device *dev,
11775 struct beacon_parameters *params)
11776{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011778 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11779 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011780 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011781
11782 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011783
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11785 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11786 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11787 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11788 __func__, hdd_device_modetoString(pAdapter->device_mode),
11789 pAdapter->device_mode);
11790
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11792 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011793 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011794 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011795 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011796 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011797
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011798 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011800 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011801 {
11802 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011803
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011805
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011807 {
11808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11809 FL("session(%d) old and new heads points to NULL"),
11810 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011812 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011813
11814 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11815
11816 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011818 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011819 return -EINVAL;
11820 }
11821
11822 pAdapter->sessionCtx.ap.beacon = new;
11823
11824 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11825 }
11826
11827 EXIT();
11828 return status;
11829}
11830
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011831static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11832 struct net_device *dev,
11833 struct beacon_parameters *params)
11834{
11835 int ret;
11836
11837 vos_ssr_protect(__func__);
11838 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11839 vos_ssr_unprotect(__func__);
11840
11841 return ret;
11842}
11843
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011844#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11845
11846#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011847static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011848 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011850static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011851 struct net_device *dev)
11852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011853{
11854 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011855 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011856 hdd_context_t *pHddCtx = NULL;
11857 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011858 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011859 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011860
11861 ENTER();
11862
11863 if (NULL == pAdapter)
11864 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011866 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 return -ENODEV;
11868 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011869
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11871 TRACE_CODE_HDD_CFG80211_STOP_AP,
11872 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011873 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11874 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011875 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011876 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011877 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011878 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011879
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011880 pScanInfo = &pHddCtx->scan_info;
11881
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11883 __func__, hdd_device_modetoString(pAdapter->device_mode),
11884 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011885
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011886 /*
11887 * if a sta connection is in progress in another adapter, disconnect
11888 * the sta and complete the sap operation. sta will reconnect
11889 * after sap stop is done.
11890 */
11891 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11892 if (staAdapter) {
11893 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11894 staAdapter->sessionId);
11895 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11896 }
11897
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011898 ret = wlan_hdd_scan_abort(pAdapter);
11899
Girish Gowli4bf7a632014-06-12 13:42:11 +053011900 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011901 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11903 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011904
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011905 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011906 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11908 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011909
Jeff Johnsone7245742012-09-05 17:12:55 -070011910 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011911 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011912 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011913 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011914 }
11915
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011916 /* Delete all associated STAs before stopping AP/P2P GO */
11917 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011918 hdd_hostapd_stop(dev);
11919
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 )
11923 {
11924 beacon_data_t *old;
11925
11926 old = pAdapter->sessionCtx.ap.beacon;
11927
11928 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011929 {
11930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11931 FL("session(%d) beacon data points to NULL"),
11932 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011934 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011935
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011937
11938 mutex_lock(&pHddCtx->sap_lock);
11939 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11940 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011941 hdd_hostapd_state_t *pHostapdState =
11942 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11943
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011944 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11945 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011946 vos_event_reset(&pHostapdState->vosEvent);
11947
Jeff Johnson4416a782013-03-25 14:17:50 -070011948 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11951
11952 if (!VOS_IS_STATUS_SUCCESS(status))
11953 {
11954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011955 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011956 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011957 }
11958 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011960 /* BSS stopped, clear the active sessions for this device mode */
11961 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 }
11963 mutex_unlock(&pHddCtx->sap_lock);
11964
11965 if(status != VOS_STATUS_SUCCESS)
11966 {
11967 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011968 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 return -EINVAL;
11970 }
11971
Jeff Johnson4416a782013-03-25 14:17:50 -070011972 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11974 ==eHAL_STATUS_FAILURE)
11975 {
11976 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011977 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 }
11979
Jeff Johnson4416a782013-03-25 14:17:50 -070011980 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11982 eANI_BOOLEAN_FALSE) )
11983 {
11984 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011985 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 }
11987
11988 // Reset WNI_CFG_PROBE_RSP Flags
11989 wlan_hdd_reset_prob_rspies(pAdapter);
11990
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011991 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11992
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 pAdapter->sessionCtx.ap.beacon = NULL;
11994 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011995#ifdef WLAN_FEATURE_P2P_DEBUG
11996 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11997 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11998 {
11999 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
12000 "GO got removed");
12001 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
12002 }
12003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012004 }
12005 EXIT();
12006 return status;
12007}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012008
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012009#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12010static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
12011 struct net_device *dev)
12012{
12013 int ret;
12014
12015 vos_ssr_protect(__func__);
12016 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
12017 vos_ssr_unprotect(__func__);
12018
12019 return ret;
12020}
12021#else
12022static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
12023 struct net_device *dev)
12024{
12025 int ret;
12026
12027 vos_ssr_protect(__func__);
12028 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
12029 vos_ssr_unprotect(__func__);
12030
12031 return ret;
12032}
12033#endif
12034
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012035#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
12036
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012037static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012038 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012039 struct cfg80211_ap_settings *params)
12040{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012041 hdd_adapter_t *pAdapter;
12042 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012043 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012044
12045 ENTER();
12046
Girish Gowlib143d7a2015-02-18 19:39:55 +053012047 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012050 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012051 return -ENODEV;
12052 }
12053
12054 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12055 if (NULL == pAdapter)
12056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012058 "%s: HDD adapter is Null", __func__);
12059 return -ENODEV;
12060 }
12061
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012062 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12063 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12064 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012065 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12066 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012068 "%s: HDD adapter magic is invalid", __func__);
12069 return -ENODEV;
12070 }
12071
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012072 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12073
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012074 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012075 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012076 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012077 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012078 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012079 }
12080
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012081 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12082 __func__, hdd_device_modetoString(pAdapter->device_mode),
12083 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012084
12085 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012086 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012087 )
12088 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012089 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012090
12091 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012092
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012093 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012094 {
12095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12096 FL("already beacon info added to session(%d)"),
12097 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012098 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012099 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012100
Girish Gowlib143d7a2015-02-18 19:39:55 +053012101#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12102 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12103 &new,
12104 &params->beacon);
12105#else
12106 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12107 &new,
12108 &params->beacon,
12109 params->dtim_period);
12110#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012111
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012112 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012113 {
12114 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012115 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 return -EINVAL;
12117 }
12118 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012119#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012120 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12121#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12122 params->channel, params->channel_type);
12123#else
12124 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12125#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012126#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012127 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012128 params->ssid_len, params->hidden_ssid,
12129 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012130 }
12131
12132 EXIT();
12133 return status;
12134}
12135
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012136static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12137 struct net_device *dev,
12138 struct cfg80211_ap_settings *params)
12139{
12140 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012141
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012142 vos_ssr_protect(__func__);
12143 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12144 vos_ssr_unprotect(__func__);
12145
12146 return ret;
12147}
12148
12149static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012150 struct net_device *dev,
12151 struct cfg80211_beacon_data *params)
12152{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012154 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012155 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012156
12157 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012158
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012159 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12160 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12161 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012163 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012164
12165 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12166 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012167 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012168 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012169 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012170 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012171
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012172 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012173 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012175 {
12176 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012177
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012178 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012180 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012181 {
12182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12183 FL("session(%d) beacon data points to NULL"),
12184 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012185 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012186 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012187
12188 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12189
12190 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012191 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012192 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012193 return -EINVAL;
12194 }
12195
12196 pAdapter->sessionCtx.ap.beacon = new;
12197
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012198 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12199 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012200 }
12201
12202 EXIT();
12203 return status;
12204}
12205
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012206static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12207 struct net_device *dev,
12208 struct cfg80211_beacon_data *params)
12209{
12210 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012211
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012212 vos_ssr_protect(__func__);
12213 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12214 vos_ssr_unprotect(__func__);
12215
12216 return ret;
12217}
12218
12219#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012220
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012221static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 struct net_device *dev,
12223 struct bss_parameters *params)
12224{
12225 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012226 hdd_context_t *pHddCtx;
12227 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012228
12229 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012230
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012231 if (NULL == pAdapter)
12232 {
12233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12234 "%s: HDD adapter is Null", __func__);
12235 return -ENODEV;
12236 }
12237 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012238 ret = wlan_hdd_validate_context(pHddCtx);
12239 if (0 != ret)
12240 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012241 return ret;
12242 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12244 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12245 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012246 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12247 __func__, hdd_device_modetoString(pAdapter->device_mode),
12248 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012249
12250 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012252 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012253 {
12254 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12255 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012256 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 {
12258 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012259 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 }
12261
12262 EXIT();
12263 return 0;
12264}
12265
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012266static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12267 struct net_device *dev,
12268 struct bss_parameters *params)
12269{
12270 int ret;
12271
12272 vos_ssr_protect(__func__);
12273 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12274 vos_ssr_unprotect(__func__);
12275
12276 return ret;
12277}
Kiet Lam10841362013-11-01 11:36:50 +053012278/* FUNCTION: wlan_hdd_change_country_code_cd
12279* to wait for contry code completion
12280*/
12281void* wlan_hdd_change_country_code_cb(void *pAdapter)
12282{
12283 hdd_adapter_t *call_back_pAdapter = pAdapter;
12284 complete(&call_back_pAdapter->change_country_code);
12285 return NULL;
12286}
12287
Jeff Johnson295189b2012-06-20 16:38:30 -070012288/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012289 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12291 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012292int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 struct net_device *ndev,
12294 enum nl80211_iftype type,
12295 u32 *flags,
12296 struct vif_params *params
12297 )
12298{
12299 struct wireless_dev *wdev;
12300 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012301 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012303 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012304 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012305 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012306 eMib_dot11DesiredBssType connectedBssType;
12307 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012308 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012309
12310 ENTER();
12311
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012312 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012313 {
12314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12315 "%s: Adapter context is null", __func__);
12316 return VOS_STATUS_E_FAILURE;
12317 }
12318
12319 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12320 if (!pHddCtx)
12321 {
12322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12323 "%s: HDD context is null", __func__);
12324 return VOS_STATUS_E_FAILURE;
12325 }
12326
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012327 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12328 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12329 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012330 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012331 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012333 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 }
12335
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12337 __func__, hdd_device_modetoString(pAdapter->device_mode),
12338 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012339
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012340 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12341 hddLog(VOS_TRACE_LEVEL_FATAL,
12342 "%s: STA + MON is in progress, cannot change interface",
12343 __func__);
12344 }
12345
Agarwal Ashish51325b52014-06-16 16:50:49 +053012346 if (vos_max_concurrent_connections_reached()) {
12347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12348 return -EINVAL;
12349 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012350 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 wdev = ndev->ieee80211_ptr;
12352
12353#ifdef WLAN_BTAMP_FEATURE
12354 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12355 (NL80211_IFTYPE_ADHOC == type)||
12356 (NL80211_IFTYPE_AP == type)||
12357 (NL80211_IFTYPE_P2P_GO == type))
12358 {
12359 pHddCtx->isAmpAllowed = VOS_FALSE;
12360 // stop AMP traffic
12361 status = WLANBAP_StopAmp();
12362 if(VOS_STATUS_SUCCESS != status )
12363 {
12364 pHddCtx->isAmpAllowed = VOS_TRUE;
12365 hddLog(VOS_TRACE_LEVEL_FATAL,
12366 "%s: Failed to stop AMP", __func__);
12367 return -EINVAL;
12368 }
12369 }
12370#endif //WLAN_BTAMP_FEATURE
12371 /* Reset the current device mode bit mask*/
12372 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12373
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012374 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12375 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12376 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012377 {
12378 /* Notify Mode change in case of concurrency.
12379 * Below function invokes TDLS teardown Functionality Since TDLS is
12380 * not Supported in case of concurrency i.e Once P2P session
12381 * is detected disable offchannel and teardown TDLS links
12382 */
12383 hddLog(LOG1,
12384 FL("Device mode = %d Interface type = %d"),
12385 pAdapter->device_mode, type);
12386 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12387 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012388
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012391 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012392 )
12393 {
12394 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012395 if (!pWextState)
12396 {
12397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12398 "%s: pWextState is null", __func__);
12399 return VOS_STATUS_E_FAILURE;
12400 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 pRoamProfile = &pWextState->roamProfile;
12402 LastBSSType = pRoamProfile->BSSType;
12403
12404 switch (type)
12405 {
12406 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 hddLog(VOS_TRACE_LEVEL_INFO,
12409 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12410 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012411#ifdef WLAN_FEATURE_11AC
12412 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12413 {
12414 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12415 }
12416#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012417 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012418 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012420 //Check for sub-string p2p to confirm its a p2p interface
12421 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012422 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012423#ifdef FEATURE_WLAN_TDLS
12424 mutex_lock(&pHddCtx->tdls_lock);
12425 wlan_hdd_tdls_exit(pAdapter, TRUE);
12426 mutex_unlock(&pHddCtx->tdls_lock);
12427#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012428 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12429 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12430 }
12431 else
12432 {
12433 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012435 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012437
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 case NL80211_IFTYPE_ADHOC:
12439 hddLog(VOS_TRACE_LEVEL_INFO,
12440 "%s: setting interface Type to ADHOC", __func__);
12441 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12442 pRoamProfile->phyMode =
12443 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012444 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012445 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012446 hdd_set_ibss_ops( pAdapter );
12447 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012448
12449 status = hdd_sta_id_hash_attach(pAdapter);
12450 if (VOS_STATUS_SUCCESS != status) {
12451 hddLog(VOS_TRACE_LEVEL_ERROR,
12452 FL("Failed to initialize hash for IBSS"));
12453 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 break;
12455
12456 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012457 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 {
12459 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12460 "%s: setting interface Type to %s", __func__,
12461 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12462
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012463 //Cancel any remain on channel for GO mode
12464 if (NL80211_IFTYPE_P2P_GO == type)
12465 {
12466 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12467 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012468 if (NL80211_IFTYPE_AP == type)
12469 {
12470 /*
12471 * As Loading WLAN Driver one interface being created
12472 * for p2p device address. This will take one HW STA and
12473 * the max number of clients that can connect to softAP
12474 * will be reduced by one. so while changing the interface
12475 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12476 * as it is not required in SoftAP mode.
12477 */
12478
12479 // Get P2P Adapter
12480 pP2pAdapter = hdd_get_adapter(pHddCtx,
12481 WLAN_HDD_P2P_DEVICE);
12482 if (pP2pAdapter)
12483 {
12484 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12485 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12486 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12487 }
12488 }
12489
Swaroop Goltia2e32212014-04-09 23:37:33 +053012490 //Disable IMPS & BMPS for SAP/GO
12491 if(VOS_STATUS_E_FAILURE ==
12492 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12493 {
12494 //Fail to Exit BMPS
12495 VOS_ASSERT(0);
12496 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012497
12498 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12499
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012500#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012501
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012502 /* A Mutex Lock is introduced while changing the mode to
12503 * protect the concurrent access for the Adapters by TDLS
12504 * module.
12505 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012506 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012507#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012509 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12512 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012513#ifdef FEATURE_WLAN_TDLS
12514 mutex_unlock(&pHddCtx->tdls_lock);
12515#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012516 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12517 (pConfig->apRandomBssidEnabled))
12518 {
12519 /* To meet Android requirements create a randomized
12520 MAC address of the form 02:1A:11:Fx:xx:xx */
12521 get_random_bytes(&ndev->dev_addr[3], 3);
12522 ndev->dev_addr[0] = 0x02;
12523 ndev->dev_addr[1] = 0x1A;
12524 ndev->dev_addr[2] = 0x11;
12525 ndev->dev_addr[3] |= 0xF0;
12526 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12527 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012528 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12529 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012530 }
12531
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 hdd_set_ap_ops( pAdapter->dev );
12533
Kiet Lam10841362013-11-01 11:36:50 +053012534 /* This is for only SAP mode where users can
12535 * control country through ini.
12536 * P2P GO follows station country code
12537 * acquired during the STA scanning. */
12538 if((NL80211_IFTYPE_AP == type) &&
12539 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12540 {
12541 int status = 0;
12542 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12543 "%s: setting country code from INI ", __func__);
12544 init_completion(&pAdapter->change_country_code);
12545 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12546 (void *)(tSmeChangeCountryCallback)
12547 wlan_hdd_change_country_code_cb,
12548 pConfig->apCntryCode, pAdapter,
12549 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012550 eSIR_FALSE,
12551 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012552 if (eHAL_STATUS_SUCCESS == status)
12553 {
12554 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012555 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012556 &pAdapter->change_country_code,
12557 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012558 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012559 {
12560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012561 FL("SME Timed out while setting country code %ld"),
12562 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012563
12564 if (pHddCtx->isLogpInProgress)
12565 {
12566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12567 "%s: LOGP in Progress. Ignore!!!", __func__);
12568 return -EAGAIN;
12569 }
Kiet Lam10841362013-11-01 11:36:50 +053012570 }
12571 }
12572 else
12573 {
12574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012575 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012576 return -EINVAL;
12577 }
12578 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012579 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 if(status != VOS_STATUS_SUCCESS)
12581 {
12582 hddLog(VOS_TRACE_LEVEL_FATAL,
12583 "%s: Error initializing the ap mode", __func__);
12584 return -EINVAL;
12585 }
12586 hdd_set_conparam(1);
12587
Nirav Shah7e3c8132015-06-22 23:51:42 +053012588 status = hdd_sta_id_hash_attach(pAdapter);
12589 if (VOS_STATUS_SUCCESS != status)
12590 {
12591 hddLog(VOS_TRACE_LEVEL_ERROR,
12592 FL("Failed to initialize hash for AP"));
12593 return -EINVAL;
12594 }
12595
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 /*interface type changed update in wiphy structure*/
12597 if(wdev)
12598 {
12599 wdev->iftype = type;
12600 pHddCtx->change_iface = type;
12601 }
12602 else
12603 {
12604 hddLog(VOS_TRACE_LEVEL_ERROR,
12605 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12606 return -EINVAL;
12607 }
12608 goto done;
12609 }
12610
12611 default:
12612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12613 __func__);
12614 return -EOPNOTSUPP;
12615 }
12616 }
12617 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 )
12620 {
12621 switch(type)
12622 {
12623 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012626
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012627 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12628 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12629 /*
12630 * The p2p interface was deleted while SoftAP mode was init,
12631 * create that interface now that the SoftAP is going down.
12632 */
12633 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12634 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12635 VOS_TRUE);
12636 }
12637
Deepthi Gowri500fc472014-08-11 19:53:10 +053012638 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012639
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012640#ifdef FEATURE_WLAN_TDLS
12641
12642 /* A Mutex Lock is introduced while changing the mode to
12643 * protect the concurrent access for the Adapters by TDLS
12644 * module.
12645 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012646 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012647#endif
c_hpothu002231a2015-02-05 14:58:51 +053012648 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012650 //Check for sub-string p2p to confirm its a p2p interface
12651 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012652 {
12653 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12654 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12655 }
12656 else
12657 {
12658 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012660 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012661
12662 /* set con_mode to STA only when no SAP concurrency mode */
12663 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12664 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012665 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12667 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012668#ifdef FEATURE_WLAN_TDLS
12669 mutex_unlock(&pHddCtx->tdls_lock);
12670#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012671 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012672 if( VOS_STATUS_SUCCESS != status )
12673 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012674 /* In case of JB, for P2P-GO, only change interface will be called,
12675 * This is the right place to enable back bmps_imps()
12676 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012677 if (pHddCtx->hdd_wlan_suspended)
12678 {
12679 hdd_set_pwrparams(pHddCtx);
12680 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012681 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 goto done;
12683 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012685 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12687 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012688 goto done;
12689 default:
12690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12691 __func__);
12692 return -EOPNOTSUPP;
12693
12694 }
12695
12696 }
12697 else
12698 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012699 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12700 __func__, hdd_device_modetoString(pAdapter->device_mode),
12701 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 return -EOPNOTSUPP;
12703 }
12704
12705
12706 if(pRoamProfile)
12707 {
12708 if ( LastBSSType != pRoamProfile->BSSType )
12709 {
12710 /*interface type changed update in wiphy structure*/
12711 wdev->iftype = type;
12712
12713 /*the BSS mode changed, We need to issue disconnect
12714 if connected or in IBSS disconnect state*/
12715 if ( hdd_connGetConnectedBssType(
12716 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12717 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12718 {
12719 /*need to issue a disconnect to CSR.*/
12720 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12721 if( eHAL_STATUS_SUCCESS ==
12722 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12723 pAdapter->sessionId,
12724 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12725 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012726 ret = wait_for_completion_interruptible_timeout(
12727 &pAdapter->disconnect_comp_var,
12728 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12729 if (ret <= 0)
12730 {
12731 hddLog(VOS_TRACE_LEVEL_ERROR,
12732 FL("wait on disconnect_comp_var failed %ld"), ret);
12733 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 }
12735 }
12736 }
12737 }
12738
12739done:
12740 /*set bitmask based on updated value*/
12741 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012742
12743 /* Only STA mode support TM now
12744 * all other mode, TM feature should be disabled */
12745 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12746 (~VOS_STA & pHddCtx->concurrency_mode) )
12747 {
12748 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12749 }
12750
Jeff Johnson295189b2012-06-20 16:38:30 -070012751#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012752 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012753 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012754 {
12755 //we are ok to do AMP
12756 pHddCtx->isAmpAllowed = VOS_TRUE;
12757 }
12758#endif //WLAN_BTAMP_FEATURE
12759 EXIT();
12760 return 0;
12761}
12762
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012763/*
12764 * FUNCTION: wlan_hdd_cfg80211_change_iface
12765 * wrapper function to protect the actual implementation from SSR.
12766 */
12767int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12768 struct net_device *ndev,
12769 enum nl80211_iftype type,
12770 u32 *flags,
12771 struct vif_params *params
12772 )
12773{
12774 int ret;
12775
12776 vos_ssr_protect(__func__);
12777 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12778 vos_ssr_unprotect(__func__);
12779
12780 return ret;
12781}
12782
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012783#ifdef FEATURE_WLAN_TDLS
12784static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012785 struct net_device *dev,
12786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12787 const u8 *mac,
12788#else
12789 u8 *mac,
12790#endif
12791 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012792{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012794 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012795 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012796 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012797 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012798 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012799
12800 ENTER();
12801
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012802 if (!dev) {
12803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12804 return -EINVAL;
12805 }
12806
12807 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12808 if (!pAdapter) {
12809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12810 return -EINVAL;
12811 }
12812
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012813 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012814 {
12815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12816 "Invalid arguments");
12817 return -EINVAL;
12818 }
Hoonki Lee27511902013-03-14 18:19:06 -070012819
12820 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12821 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12822 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012824 "%s: TDLS mode is disabled OR not enabled in FW."
12825 MAC_ADDRESS_STR " Request declined.",
12826 __func__, MAC_ADDR_ARRAY(mac));
12827 return -ENOTSUPP;
12828 }
12829
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012830 if (pHddCtx->isLogpInProgress)
12831 {
12832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12833 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012834 wlan_hdd_tdls_set_link_status(pAdapter,
12835 mac,
12836 eTDLS_LINK_IDLE,
12837 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012838 return -EBUSY;
12839 }
12840
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012841 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012842 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012843
12844 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012846 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12847 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012848 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012849 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012850 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012851
12852 /* in add station, we accept existing valid staId if there is */
12853 if ((0 == update) &&
12854 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12855 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012856 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012858 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012859 " link_status %d. staId %d. add station ignored.",
12860 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012861 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012862 return 0;
12863 }
12864 /* in change station, we accept only when staId is valid */
12865 if ((1 == update) &&
12866 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12867 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12868 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012869 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012871 "%s: " MAC_ADDRESS_STR
12872 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012873 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12874 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12875 mutex_unlock(&pHddCtx->tdls_lock);
12876 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012877 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012878 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012879
12880 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012881 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012882 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12884 "%s: " MAC_ADDRESS_STR
12885 " TDLS setup is ongoing. Request declined.",
12886 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012887 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012888 }
12889
12890 /* first to check if we reached to maximum supported TDLS peer.
12891 TODO: for now, return -EPERM looks working fine,
12892 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012893 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12894 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012895 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12897 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012898 " TDLS Max peer already connected. Request declined."
12899 " Num of peers (%d), Max allowed (%d).",
12900 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12901 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012902 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012903 }
12904 else
12905 {
12906 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012907 mutex_lock(&pHddCtx->tdls_lock);
12908 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012909 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012910 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012911 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12913 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12914 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012915 return -EPERM;
12916 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012917 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012918 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012919 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012920 wlan_hdd_tdls_set_link_status(pAdapter,
12921 mac,
12922 eTDLS_LINK_CONNECTING,
12923 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012924
Jeff Johnsond75fe012013-04-06 10:53:06 -070012925 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012926 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012927 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012929 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012930 if(StaParams->htcap_present)
12931 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012933 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012935 "ht_capa->extended_capabilities: %0x",
12936 StaParams->HTCap.extendedHtCapInfo);
12937 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012939 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012941 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012942 if(StaParams->vhtcap_present)
12943 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012945 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12946 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12947 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12948 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012949 {
12950 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012952 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012954 "[%d]: %x ", i, StaParams->supported_rates[i]);
12955 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012956 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012957 else if ((1 == update) && (NULL == StaParams))
12958 {
12959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12960 "%s : update is true, but staParams is NULL. Error!", __func__);
12961 return -EPERM;
12962 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012963
12964 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12965
12966 if (!update)
12967 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012968 /*Before adding sta make sure that device exited from BMPS*/
12969 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12970 {
12971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12972 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12973 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12974 if (status != VOS_STATUS_SUCCESS) {
12975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12976 }
12977 }
12978
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012979 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012980 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012981 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012982 hddLog(VOS_TRACE_LEVEL_ERROR,
12983 FL("Failed to add TDLS peer STA. Enable Bmps"));
12984 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012985 return -EPERM;
12986 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012987 }
12988 else
12989 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012990 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012991 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012992 if (ret != eHAL_STATUS_SUCCESS) {
12993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12994 return -EPERM;
12995 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012996 }
12997
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012998 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012999 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
13000
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053013001 mutex_lock(&pHddCtx->tdls_lock);
13002 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
13003
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013004 if ((pTdlsPeer != NULL) &&
13005 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013006 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013007 hddLog(VOS_TRACE_LEVEL_ERROR,
13008 FL("peer link status %u"), pTdlsPeer->link_status);
13009 mutex_unlock(&pHddCtx->tdls_lock);
13010 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013011 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053013012 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013013
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013014 if (ret <= 0)
13015 {
13016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13017 "%s: timeout waiting for tdls add station indication %ld",
13018 __func__, ret);
13019 goto error;
13020 }
13021
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013022 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
13023 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013025 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013026 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013027 }
13028
13029 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013030
13031error:
Atul Mittal115287b2014-07-08 13:26:33 +053013032 wlan_hdd_tdls_set_link_status(pAdapter,
13033 mac,
13034 eTDLS_LINK_IDLE,
13035 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013036 return -EPERM;
13037
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013038}
13039#endif
13040
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013041VOS_STATUS wlan_hdd_send_sta_authorized_event(
13042 hdd_adapter_t *adapter,
13043 hdd_context_t *hdd_ctx,
13044 const v_MACADDR_t *mac_addr)
13045{
13046 struct sk_buff *vendor_event;
13047 uint32_t sta_flags = 0;
13048 VOS_STATUS status;
13049
13050 ENTER();
13051
13052 if (!hdd_ctx) {
13053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13054 return -EINVAL;
13055 }
13056
13057 vendor_event =
13058 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013059 hdd_ctx->wiphy,
13060#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13061 &adapter->wdev,
13062#endif
13063 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013064 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13065 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13066 GFP_KERNEL);
13067 if (!vendor_event) {
13068 hddLog(VOS_TRACE_LEVEL_ERROR,
13069 FL("cfg80211_vendor_event_alloc failed"));
13070 return -EINVAL;
13071 }
13072
13073 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13074
13075 status = nla_put_u32(vendor_event,
13076 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13077 sta_flags);
13078 if (status) {
13079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13080 kfree_skb(vendor_event);
13081 return VOS_STATUS_E_FAILURE;
13082 }
13083 status = nla_put(vendor_event,
13084 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13085 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13086 if (status) {
13087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13088 kfree_skb(vendor_event);
13089 return VOS_STATUS_E_FAILURE;
13090 }
13091
13092 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13093
13094 EXIT();
13095 return 0;
13096}
13097
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013098static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13101 const u8 *mac,
13102#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013104#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 struct station_parameters *params)
13106{
13107 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013108 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013109 hdd_context_t *pHddCtx;
13110 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013111 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013112 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013113#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013114 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013115 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013116 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013117 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013118#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013119
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013120 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013121
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013122 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013123 if ((NULL == pAdapter))
13124 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013126 "invalid adapter ");
13127 return -EINVAL;
13128 }
13129
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013130 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13131 TRACE_CODE_HDD_CHANGE_STATION,
13132 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013133 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013134
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013135 ret = wlan_hdd_validate_context(pHddCtx);
13136 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013137 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013138 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013139 }
13140
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013141 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13142
13143 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013144 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13146 "invalid HDD station context");
13147 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013148 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13150
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013151 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13152 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013153 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013154 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013155 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013156 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013157 WLANTL_STA_AUTHENTICATED);
13158
Gopichand Nakkala29149562013-05-10 21:43:41 +053013159 if (status != VOS_STATUS_SUCCESS)
13160 {
13161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13162 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13163 return -EINVAL;
13164 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013165 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13166 &STAMacAddress);
13167 if (status != VOS_STATUS_SUCCESS)
13168 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 }
13170 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013171 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13172 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013173#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013174 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13175 StaParams.capability = params->capability;
13176 StaParams.uapsd_queues = params->uapsd_queues;
13177 StaParams.max_sp = params->max_sp;
13178
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013179 /* Convert (first channel , number of channels) tuple to
13180 * the total list of channels. This goes with the assumption
13181 * that if the first channel is < 14, then the next channels
13182 * are an incremental of 1 else an incremental of 4 till the number
13183 * of channels.
13184 */
13185 if (0 != params->supported_channels_len) {
13186 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013187 for ( i = 0 ; i < params->supported_channels_len
13188 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013189 {
13190 int wifi_chan_index;
13191 StaParams.supported_channels[j] = params->supported_channels[i];
13192 wifi_chan_index =
13193 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13194 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013195 for(k=1; k <= no_of_channels
13196 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013197 {
13198 StaParams.supported_channels[j+1] =
13199 StaParams.supported_channels[j] + wifi_chan_index;
13200 j+=1;
13201 }
13202 }
13203 StaParams.supported_channels_len = j;
13204 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013205 if (params->supported_oper_classes_len >
13206 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13208 "received oper classes:%d, resetting it to max supported %d",
13209 params->supported_oper_classes_len,
13210 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13211 params->supported_oper_classes_len =
13212 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13213 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013214 vos_mem_copy(StaParams.supported_oper_classes,
13215 params->supported_oper_classes,
13216 params->supported_oper_classes_len);
13217 StaParams.supported_oper_classes_len =
13218 params->supported_oper_classes_len;
13219
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013220 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13222 "received extn capabilities:%d, resetting it to max supported",
13223 params->ext_capab_len);
13224 params->ext_capab_len = sizeof(StaParams.extn_capability);
13225 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013226 if (0 != params->ext_capab_len)
13227 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013228 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013229
13230 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013231 {
13232 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013233 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013234 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013235
13236 StaParams.supported_rates_len = params->supported_rates_len;
13237
13238 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13239 * The supported_rates array , for all the structures propogating till Add Sta
13240 * to the firmware has to be modified , if the supplicant (ieee80211) is
13241 * modified to send more rates.
13242 */
13243
13244 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13245 */
13246 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13247 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13248
13249 if (0 != StaParams.supported_rates_len) {
13250 int i = 0;
13251 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13252 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013254 "Supported Rates with Length %d", StaParams.supported_rates_len);
13255 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013257 "[%d]: %0x", i, StaParams.supported_rates[i]);
13258 }
13259
13260 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013261 {
13262 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013263 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013264 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013265
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013266 if (0 != params->ext_capab_len ) {
13267 /*Define A Macro : TODO Sunil*/
13268 if ((1<<4) & StaParams.extn_capability[3]) {
13269 isBufSta = 1;
13270 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013271 /* TDLS Channel Switching Support */
13272 if ((1<<6) & StaParams.extn_capability[3]) {
13273 isOffChannelSupported = 1;
13274 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013275 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013276
13277 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013278 (params->ht_capa || params->vht_capa ||
13279 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013280 /* TDLS Peer is WME/QoS capable */
13281 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013282
13283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13284 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13285 __func__, isQosWmmSta, StaParams.htcap_present);
13286
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013287 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13288 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013289 isOffChannelSupported,
13290 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013291
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013292 if (VOS_STATUS_SUCCESS != status) {
13293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13294 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13295 return -EINVAL;
13296 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013297 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13298
13299 if (VOS_STATUS_SUCCESS != status) {
13300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13301 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13302 return -EINVAL;
13303 }
13304 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013305#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013306 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013307 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013308 return status;
13309}
13310
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13312static int wlan_hdd_change_station(struct wiphy *wiphy,
13313 struct net_device *dev,
13314 const u8 *mac,
13315 struct station_parameters *params)
13316#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013317static int wlan_hdd_change_station(struct wiphy *wiphy,
13318 struct net_device *dev,
13319 u8 *mac,
13320 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013321#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013322{
13323 int ret;
13324
13325 vos_ssr_protect(__func__);
13326 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13327 vos_ssr_unprotect(__func__);
13328
13329 return ret;
13330}
13331
Jeff Johnson295189b2012-06-20 16:38:30 -070013332/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013333 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013334 * This function is used to initialize the key information
13335 */
13336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013337static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013338 struct net_device *ndev,
13339 u8 key_index, bool pairwise,
13340 const u8 *mac_addr,
13341 struct key_params *params
13342 )
13343#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013344static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 struct net_device *ndev,
13346 u8 key_index, const u8 *mac_addr,
13347 struct key_params *params
13348 )
13349#endif
13350{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013351 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 tCsrRoamSetKey setKey;
13353 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013354 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013355 v_U32_t roamId= 0xFF;
13356 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 hdd_hostapd_state_t *pHostapdState;
13358 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013359 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013360 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013361 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013362 v_MACADDR_t *peerMacAddr;
13363 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013364 uint8_t staid = HDD_MAX_STA_COUNT;
13365 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013366
13367 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013368
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013369 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13370 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13371 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013372 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13373 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013374 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013376 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013377 }
13378
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13380 __func__, hdd_device_modetoString(pAdapter->device_mode),
13381 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013382
13383 if (CSR_MAX_NUM_KEY <= key_index)
13384 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 key_index);
13387
13388 return -EINVAL;
13389 }
13390
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013391 if (CSR_MAX_KEY_LEN < params->key_len)
13392 {
13393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13394 params->key_len);
13395
13396 return -EINVAL;
13397 }
13398
Jingxiang Gec438aea2017-10-26 16:44:00 +080013399 if (CSR_MAX_RSC_LEN < params->seq_len)
13400 {
13401 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13402 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013403
13404 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013405 }
13406
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013407 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013408 "%s: called with key index = %d & key length %d & seq length %d",
13409 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013410
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013411 peerMacAddr = (v_MACADDR_t *)mac_addr;
13412
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 /*extract key idx, key len and key*/
13414 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13415 setKey.keyId = key_index;
13416 setKey.keyLength = params->key_len;
13417 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013418 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013419
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013420 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013421 {
13422 case WLAN_CIPHER_SUITE_WEP40:
13423 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13424 break;
13425
13426 case WLAN_CIPHER_SUITE_WEP104:
13427 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13428 break;
13429
13430 case WLAN_CIPHER_SUITE_TKIP:
13431 {
13432 u8 *pKey = &setKey.Key[0];
13433 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13434
13435 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13436
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013437 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013438
13439 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013440 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013441 |--------------|----------|----------|
13442 <---16bytes---><--8bytes--><--8bytes-->
13443
13444 */
13445 /*Sme expects the 32 bytes key to be in the below order
13446
13447 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013448 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013449 |--------------|----------|----------|
13450 <---16bytes---><--8bytes--><--8bytes-->
13451 */
13452 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013453 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013454
13455 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013456 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013457
13458 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013459 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013460
13461
13462 break;
13463 }
13464
13465 case WLAN_CIPHER_SUITE_CCMP:
13466 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13467 break;
13468
13469#ifdef FEATURE_WLAN_WAPI
13470 case WLAN_CIPHER_SUITE_SMS4:
13471 {
13472 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13473 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13474 params->key, params->key_len);
13475 return 0;
13476 }
13477#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013478
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013479#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 case WLAN_CIPHER_SUITE_KRK:
13481 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13482 break;
13483#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013484
13485#ifdef WLAN_FEATURE_11W
13486 case WLAN_CIPHER_SUITE_AES_CMAC:
13487 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013488 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013489#endif
13490
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013494 status = -EOPNOTSUPP;
13495 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 }
13497
13498 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13499 __func__, setKey.encType);
13500
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013501 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013502#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13503 (!pairwise)
13504#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013505 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013506#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013507 )
13508 {
13509 /* set group key*/
13510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13511 "%s- %d: setting Broadcast key",
13512 __func__, __LINE__);
13513 setKey.keyDirection = eSIR_RX_ONLY;
13514 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13515 }
13516 else
13517 {
13518 /* set pairwise key*/
13519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13520 "%s- %d: setting pairwise key",
13521 __func__, __LINE__);
13522 setKey.keyDirection = eSIR_TX_RX;
13523 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013524 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013525 }
13526 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13527 {
13528 setKey.keyDirection = eSIR_TX_RX;
13529 /*Set the group key*/
13530 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13531 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013532
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013533 if ( 0 != status )
13534 {
13535 hddLog(VOS_TRACE_LEVEL_ERROR,
13536 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013537 status = -EINVAL;
13538 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013539 }
13540 /*Save the keys here and call sme_RoamSetKey for setting
13541 the PTK after peer joins the IBSS network*/
13542 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13543 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013544 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013545 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013546 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13547 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13548 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013550 if( pHostapdState->bssState == BSS_START )
13551 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013552 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13553 vos_status = wlan_hdd_check_ula_done(pAdapter);
13554
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013555 if (peerMacAddr && (pairwise_set_key == true))
13556 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013557
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013558 if ( vos_status != VOS_STATUS_SUCCESS )
13559 {
13560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13561 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13562 __LINE__, vos_status );
13563
13564 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13565
13566 status = -EINVAL;
13567 goto end;
13568 }
13569
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13571
13572 if ( status != eHAL_STATUS_SUCCESS )
13573 {
13574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13575 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13576 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013577 status = -EINVAL;
13578 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 }
13580 }
13581
13582 /* Saving WEP keys */
13583 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13584 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13585 {
13586 //Save the wep key in ap context. Issue setkey after the BSS is started.
13587 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13588 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13589 }
13590 else
13591 {
13592 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013593 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13595 }
13596 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013597 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13598 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 {
13600 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13601 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13602
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13604 if (!pairwise)
13605#else
13606 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13607#endif
13608 {
13609 /* set group key*/
13610 if (pHddStaCtx->roam_info.deferKeyComplete)
13611 {
13612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13613 "%s- %d: Perform Set key Complete",
13614 __func__, __LINE__);
13615 hdd_PerformRoamSetKeyComplete(pAdapter);
13616 }
13617 }
13618
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013619 if (pairwise_set_key == true)
13620 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013621
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13623
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013624 pWextState->roamProfile.Keys.defaultIndex = key_index;
13625
13626
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013627 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013628 params->key, params->key_len);
13629
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013630
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13632
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013633 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635 __func__, setKey.peerMac[0], setKey.peerMac[1],
13636 setKey.peerMac[2], setKey.peerMac[3],
13637 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013638 setKey.keyDirection);
13639
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013640 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013641
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013642 if ( vos_status != VOS_STATUS_SUCCESS )
13643 {
13644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13646 __LINE__, vos_status );
13647
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013648 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013649
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013650 status = -EINVAL;
13651 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013652
13653 }
13654
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013655#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013656 /* The supplicant may attempt to set the PTK once pre-authentication
13657 is done. Save the key in the UMAC and include it in the ADD BSS
13658 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013659 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013660 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013661 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013662 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13663 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013664 status = 0;
13665 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013666 }
13667 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13668 {
13669 hddLog(VOS_TRACE_LEVEL_ERROR,
13670 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013671 status = -EINVAL;
13672 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013673 }
13674#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013675
13676 /* issue set key request to SME*/
13677 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13678 pAdapter->sessionId, &setKey, &roamId );
13679
13680 if ( 0 != status )
13681 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013682 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013683 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13684 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013685 status = -EINVAL;
13686 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 }
13688
13689
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013690 /* in case of IBSS as there was no information available about WEP keys during
13691 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013693 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13694 !( ( IW_AUTH_KEY_MGMT_802_1X
13695 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013696 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13697 )
13698 &&
13699 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13700 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13701 )
13702 )
13703 {
13704 setKey.keyDirection = eSIR_RX_ONLY;
13705 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13706
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013707 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013708 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013709 __func__, setKey.peerMac[0], setKey.peerMac[1],
13710 setKey.peerMac[2], setKey.peerMac[3],
13711 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 setKey.keyDirection);
13713
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013714 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 pAdapter->sessionId, &setKey, &roamId );
13716
13717 if ( 0 != status )
13718 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719 hddLog(VOS_TRACE_LEVEL_ERROR,
13720 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013721 __func__, status);
13722 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013723 status = -EINVAL;
13724 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 }
13726 }
13727 }
13728
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013729 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013730 for (i = 0; i < params->seq_len; i++) {
13731 rsc_counter |= (params->seq[i] << i*8);
13732 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013733 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13734 }
13735
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013736end:
13737 /* Need to clear any trace of key value in the memory.
13738 * Thus zero out the memory even though it is local
13739 * variable.
13740 */
13741 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013742 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013743 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013744}
13745
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13747static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13748 struct net_device *ndev,
13749 u8 key_index, bool pairwise,
13750 const u8 *mac_addr,
13751 struct key_params *params
13752 )
13753#else
13754static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13755 struct net_device *ndev,
13756 u8 key_index, const u8 *mac_addr,
13757 struct key_params *params
13758 )
13759#endif
13760{
13761 int ret;
13762 vos_ssr_protect(__func__);
13763#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13764 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13765 mac_addr, params);
13766#else
13767 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13768 params);
13769#endif
13770 vos_ssr_unprotect(__func__);
13771
13772 return ret;
13773}
13774
Jeff Johnson295189b2012-06-20 16:38:30 -070013775/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013776 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 * This function is used to get the key information
13778 */
13779#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013780static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013781 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013782 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013783 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 const u8 *mac_addr, void *cookie,
13785 void (*callback)(void *cookie, struct key_params*)
13786 )
13787#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013788static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013789 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 struct net_device *ndev,
13791 u8 key_index, const u8 *mac_addr, void *cookie,
13792 void (*callback)(void *cookie, struct key_params*)
13793 )
13794#endif
13795{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013797 hdd_wext_state_t *pWextState = NULL;
13798 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013800 hdd_context_t *pHddCtx;
13801 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013802
13803 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013804
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013805 if (NULL == pAdapter)
13806 {
13807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13808 "%s: HDD adapter is Null", __func__);
13809 return -ENODEV;
13810 }
13811
13812 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13813 ret = wlan_hdd_validate_context(pHddCtx);
13814 if (0 != ret)
13815 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013816 return ret;
13817 }
13818
13819 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13820 pRoamProfile = &(pWextState->roamProfile);
13821
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13823 __func__, hdd_device_modetoString(pAdapter->device_mode),
13824 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013825
Jeff Johnson295189b2012-06-20 16:38:30 -070013826 memset(&params, 0, sizeof(params));
13827
13828 if (CSR_MAX_NUM_KEY <= key_index)
13829 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013830 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013832 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013833
13834 switch(pRoamProfile->EncryptionType.encryptionType[0])
13835 {
13836 case eCSR_ENCRYPT_TYPE_NONE:
13837 params.cipher = IW_AUTH_CIPHER_NONE;
13838 break;
13839
13840 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13841 case eCSR_ENCRYPT_TYPE_WEP40:
13842 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13843 break;
13844
13845 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13846 case eCSR_ENCRYPT_TYPE_WEP104:
13847 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13848 break;
13849
13850 case eCSR_ENCRYPT_TYPE_TKIP:
13851 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13852 break;
13853
13854 case eCSR_ENCRYPT_TYPE_AES:
13855 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13856 break;
13857
13858 default:
13859 params.cipher = IW_AUTH_CIPHER_NONE;
13860 break;
13861 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013862
c_hpothuaaf19692014-05-17 17:01:48 +053013863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13864 TRACE_CODE_HDD_CFG80211_GET_KEY,
13865 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013866
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13868 params.seq_len = 0;
13869 params.seq = NULL;
13870 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13871 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013872 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 return 0;
13874}
13875
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13877static int wlan_hdd_cfg80211_get_key(
13878 struct wiphy *wiphy,
13879 struct net_device *ndev,
13880 u8 key_index, bool pairwise,
13881 const u8 *mac_addr, void *cookie,
13882 void (*callback)(void *cookie, struct key_params*)
13883 )
13884#else
13885static int wlan_hdd_cfg80211_get_key(
13886 struct wiphy *wiphy,
13887 struct net_device *ndev,
13888 u8 key_index, const u8 *mac_addr, void *cookie,
13889 void (*callback)(void *cookie, struct key_params*)
13890 )
13891#endif
13892{
13893 int ret;
13894
13895 vos_ssr_protect(__func__);
13896#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13897 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13898 mac_addr, cookie, callback);
13899#else
13900 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13901 callback);
13902#endif
13903 vos_ssr_unprotect(__func__);
13904
13905 return ret;
13906}
13907
Jeff Johnson295189b2012-06-20 16:38:30 -070013908/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013909 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013910 * This function is used to delete the key information
13911 */
13912#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013913static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013915 u8 key_index,
13916 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 const u8 *mac_addr
13918 )
13919#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013920static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 struct net_device *ndev,
13922 u8 key_index,
13923 const u8 *mac_addr
13924 )
13925#endif
13926{
13927 int status = 0;
13928
13929 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013930 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013931 //it is observed that this is invalidating peer
13932 //key index whenever re-key is done. This is affecting data link.
13933 //It should be ok to ignore del_key.
13934#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13936 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013937 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13938 tCsrRoamSetKey setKey;
13939 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013940
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 ENTER();
13942
13943 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13944 __func__,pAdapter->device_mode);
13945
13946 if (CSR_MAX_NUM_KEY <= key_index)
13947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013949 key_index);
13950
13951 return -EINVAL;
13952 }
13953
13954 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13955 setKey.keyId = key_index;
13956
13957 if (mac_addr)
13958 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13959 else
13960 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13961
13962 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13963
13964 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013966 )
13967 {
13968
13969 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13971 if( pHostapdState->bssState == BSS_START)
13972 {
13973 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013974
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 if ( status != eHAL_STATUS_SUCCESS )
13976 {
13977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13978 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13979 __LINE__, status );
13980 }
13981 }
13982 }
13983 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 )
13986 {
13987 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13988
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013989 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13990
13991 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013993 __func__, setKey.peerMac[0], setKey.peerMac[1],
13994 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013996 if(pAdapter->sessionCtx.station.conn_info.connState ==
13997 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013999 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014001
Jeff Johnson295189b2012-06-20 16:38:30 -070014002 if ( 0 != status )
14003 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014004 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 "%s: sme_RoamSetKey failure, returned %d",
14006 __func__, status);
14007 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
14008 return -EINVAL;
14009 }
14010 }
14011 }
14012#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014013 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 return status;
14015}
14016
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14018static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14019 struct net_device *ndev,
14020 u8 key_index,
14021 bool pairwise,
14022 const u8 *mac_addr
14023 )
14024#else
14025static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14026 struct net_device *ndev,
14027 u8 key_index,
14028 const u8 *mac_addr
14029 )
14030#endif
14031{
14032 int ret;
14033
14034 vos_ssr_protect(__func__);
14035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14036 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
14037 mac_addr);
14038#else
14039 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14040#endif
14041 vos_ssr_unprotect(__func__);
14042
14043 return ret;
14044}
14045
Jeff Johnson295189b2012-06-20 16:38:30 -070014046/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014047 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 * This function is used to set the default tx key index
14049 */
14050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014051static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 struct net_device *ndev,
14053 u8 key_index,
14054 bool unicast, bool multicast)
14055#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014056static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014057 struct net_device *ndev,
14058 u8 key_index)
14059#endif
14060{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014062 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014063 hdd_wext_state_t *pWextState;
14064 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014065 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014066
14067 ENTER();
14068
Gopichand Nakkala29149562013-05-10 21:43:41 +053014069 if ((NULL == pAdapter))
14070 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014072 "invalid adapter");
14073 return -EINVAL;
14074 }
14075
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014076 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14077 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14078 pAdapter->sessionId, key_index));
14079
Gopichand Nakkala29149562013-05-10 21:43:41 +053014080 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14081 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14082
14083 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14084 {
14085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14086 "invalid Wext state or HDD context");
14087 return -EINVAL;
14088 }
14089
Arif Hussain6d2a3322013-11-17 19:50:10 -080014090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014092
Jeff Johnson295189b2012-06-20 16:38:30 -070014093 if (CSR_MAX_NUM_KEY <= key_index)
14094 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014096 key_index);
14097
14098 return -EINVAL;
14099 }
14100
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14102 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014103 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014105 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014106 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014107
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014110 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014112 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014113 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014114#ifdef FEATURE_WLAN_WAPI
14115 (eCSR_ENCRYPT_TYPE_WPI !=
14116 pHddStaCtx->conn_info.ucEncryptionType) &&
14117#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014118 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014119 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014121 {
14122 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014123 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014124
Jeff Johnson295189b2012-06-20 16:38:30 -070014125 tCsrRoamSetKey setKey;
14126 v_U32_t roamId= 0xFF;
14127 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014128
14129 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014130 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014131
Jeff Johnson295189b2012-06-20 16:38:30 -070014132 Keys->defaultIndex = (u8)key_index;
14133 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14134 setKey.keyId = key_index;
14135 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014136
14137 vos_mem_copy(&setKey.Key[0],
14138 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014139 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014140
Gopichand Nakkala29149562013-05-10 21:43:41 +053014141 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014142
14143 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014144 &pHddStaCtx->conn_info.bssId[0],
14145 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014146
Gopichand Nakkala29149562013-05-10 21:43:41 +053014147 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14148 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14149 eCSR_ENCRYPT_TYPE_WEP104)
14150 {
14151 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14152 even though ap is configured for WEP-40 encryption. In this canse the key length
14153 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14154 type(104) and switching encryption type to 40*/
14155 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14156 eCSR_ENCRYPT_TYPE_WEP40;
14157 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14158 eCSR_ENCRYPT_TYPE_WEP40;
14159 }
14160
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014161 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014162 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014163
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014165 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014166 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014167
Jeff Johnson295189b2012-06-20 16:38:30 -070014168 if ( 0 != status )
14169 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014170 hddLog(VOS_TRACE_LEVEL_ERROR,
14171 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014172 status);
14173 return -EINVAL;
14174 }
14175 }
14176 }
14177
14178 /* In SoftAp mode setting key direction for default mode */
14179 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14180 {
14181 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14182 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14183 (eCSR_ENCRYPT_TYPE_AES !=
14184 pWextState->roamProfile.EncryptionType.encryptionType[0])
14185 )
14186 {
14187 /* Saving key direction for default key index to TX default */
14188 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14189 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14190 }
14191 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014192 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014193 return status;
14194}
14195
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14197static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14198 struct net_device *ndev,
14199 u8 key_index,
14200 bool unicast, bool multicast)
14201#else
14202static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14203 struct net_device *ndev,
14204 u8 key_index)
14205#endif
14206{
14207 int ret;
14208 vos_ssr_protect(__func__);
14209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14210 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14211 multicast);
14212#else
14213 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14214#endif
14215 vos_ssr_unprotect(__func__);
14216
14217 return ret;
14218}
14219
Jeff Johnson295189b2012-06-20 16:38:30 -070014220/*
14221 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14222 * This function is used to inform the BSS details to nl80211 interface.
14223 */
14224static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14225 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14226{
14227 struct net_device *dev = pAdapter->dev;
14228 struct wireless_dev *wdev = dev->ieee80211_ptr;
14229 struct wiphy *wiphy = wdev->wiphy;
14230 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14231 int chan_no;
14232 int ie_length;
14233 const char *ie;
14234 unsigned int freq;
14235 struct ieee80211_channel *chan;
14236 int rssi = 0;
14237 struct cfg80211_bss *bss = NULL;
14238
Jeff Johnson295189b2012-06-20 16:38:30 -070014239 if( NULL == pBssDesc )
14240 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014241 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014242 return bss;
14243 }
14244
14245 chan_no = pBssDesc->channelId;
14246 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14247 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14248
14249 if( NULL == ie )
14250 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014251 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014252 return bss;
14253 }
14254
14255#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14256 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14257 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014258 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014259 }
14260 else
14261 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014262 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 }
14264#else
14265 freq = ieee80211_channel_to_frequency(chan_no);
14266#endif
14267
14268 chan = __ieee80211_get_channel(wiphy, freq);
14269
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014270 if (!chan) {
14271 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14272 return NULL;
14273 }
14274
Abhishek Singhaee43942014-06-16 18:55:47 +053014275 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014276
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014277 return cfg80211_inform_bss(wiphy, chan,
14278#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14279 CFG80211_BSS_FTYPE_UNKNOWN,
14280#endif
14281 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014282 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014283 pBssDesc->capabilityInfo,
14284 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014285 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014286}
14287
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014288/*
14289 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14290 * interface that BSS might have been lost.
14291 * @pAdapter: adaptor
14292 * @bssid: bssid which might have been lost
14293 *
14294 * Return: bss which is unlinked from kernel cache
14295 */
14296struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14297 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14298{
14299 struct net_device *dev = pAdapter->dev;
14300 struct wireless_dev *wdev = dev->ieee80211_ptr;
14301 struct wiphy *wiphy = wdev->wiphy;
14302 struct cfg80211_bss *bss = NULL;
14303
Abhishek Singh5a597e62016-12-05 15:16:30 +053014304 bss = hdd_get_bss_entry(wiphy,
14305 NULL, bssid,
14306 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014307 if (bss == NULL) {
14308 hddLog(LOGE, FL("BSS not present"));
14309 } else {
14310 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14311 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14312 cfg80211_unlink_bss(wiphy, bss);
14313 }
14314 return bss;
14315}
Jeff Johnson295189b2012-06-20 16:38:30 -070014316
14317
14318/*
14319 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14320 * This function is used to inform the BSS details to nl80211 interface.
14321 */
14322struct cfg80211_bss*
14323wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14324 tSirBssDescription *bss_desc
14325 )
14326{
14327 /*
14328 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14329 already exists in bss data base of cfg80211 for that particular BSS ID.
14330 Using cfg80211_inform_bss_frame to update the bss entry instead of
14331 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14332 now there is no possibility to get the mgmt(probe response) frame from PE,
14333 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14334 cfg80211_inform_bss_frame.
14335 */
14336 struct net_device *dev = pAdapter->dev;
14337 struct wireless_dev *wdev = dev->ieee80211_ptr;
14338 struct wiphy *wiphy = wdev->wiphy;
14339 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014340#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14341 qcom_ie_age *qie_age = NULL;
14342 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14343#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014344 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014345#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 const char *ie =
14347 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14348 unsigned int freq;
14349 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014350 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014352 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14353 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014355 hdd_context_t *pHddCtx;
14356 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014357#ifdef WLAN_OPEN_SOURCE
14358 struct timespec ts;
14359#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014361
Wilson Yangf80a0542013-10-07 13:02:37 -070014362 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14363 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014364 if (0 != status)
14365 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014366 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014367 }
14368
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014369 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014370 if (!mgmt)
14371 {
14372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14373 "%s: memory allocation failed ", __func__);
14374 return NULL;
14375 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014376
Jeff Johnson295189b2012-06-20 16:38:30 -070014377 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014378
14379#ifdef WLAN_OPEN_SOURCE
14380 /* Android does not want the timestamp from the frame.
14381 Instead it wants a monotonic increasing value */
14382 get_monotonic_boottime(&ts);
14383 mgmt->u.probe_resp.timestamp =
14384 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14385#else
14386 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014387 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14388 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014389
14390#endif
14391
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14393 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014394
14395#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14396 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14397 /* Assuming this is the last IE, copy at the end */
14398 ie_length -=sizeof(qcom_ie_age);
14399 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14400 qie_age->element_id = QCOM_VENDOR_IE_ID;
14401 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14402 qie_age->oui_1 = QCOM_OUI1;
14403 qie_age->oui_2 = QCOM_OUI2;
14404 qie_age->oui_3 = QCOM_OUI3;
14405 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014406 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14407 * bss related timestamp is in units of ms. Due to this when scan results
14408 * are sent to lowi the scan age is high.To address this, send age in units
14409 * of 1/10 ms.
14410 */
14411 qie_age->age = (vos_timer_get_system_time() -
14412 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014413#endif
14414
Jeff Johnson295189b2012-06-20 16:38:30 -070014415 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014416 if (bss_desc->fProbeRsp)
14417 {
14418 mgmt->frame_control |=
14419 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14420 }
14421 else
14422 {
14423 mgmt->frame_control |=
14424 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14425 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014426
14427#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014428 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014429 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014430 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014431 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014432 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014433 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014434 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014435
14436 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014437 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014438 }
14439 else
14440 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014441 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14442 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014443 kfree(mgmt);
14444 return NULL;
14445 }
14446#else
14447 freq = ieee80211_channel_to_frequency(chan_no);
14448#endif
14449 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014450 /*when the band is changed on the fly using the GUI, three things are done
14451 * 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)
14452 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14453 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14454 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14455 * and discards the channels correponding to previous band and calls back with zero bss results.
14456 * 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
14457 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14458 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14459 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14460 * So drop the bss and continue to next bss.
14461 */
14462 if(chan == NULL)
14463 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014464 hddLog(VOS_TRACE_LEVEL_ERROR,
14465 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14466 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014467 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014468 return NULL;
14469 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014470 /*To keep the rssi icon of the connected AP in the scan window
14471 *and the rssi icon of the wireless networks in sync
14472 * */
14473 if (( eConnectionState_Associated ==
14474 pAdapter->sessionCtx.station.conn_info.connState ) &&
14475 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14476 pAdapter->sessionCtx.station.conn_info.bssId,
14477 WNI_CFG_BSSID_LEN)) &&
14478 (pHddCtx->hdd_wlan_suspended == FALSE))
14479 {
14480 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14481 rssi = (pAdapter->rssi * 100);
14482 }
14483 else
14484 {
14485 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14486 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014487
Nirav Shah20ac06f2013-12-12 18:14:06 +053014488 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014489 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14490 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014491
Jeff Johnson295189b2012-06-20 16:38:30 -070014492 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14493 frame_len, rssi, GFP_KERNEL);
14494 kfree(mgmt);
14495 return bss_status;
14496}
14497
14498/*
14499 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14500 * This function is used to update the BSS data base of CFG8011
14501 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014502struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 tCsrRoamInfo *pRoamInfo
14504 )
14505{
14506 tCsrRoamConnectedProfile roamProfile;
14507 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14508 struct cfg80211_bss *bss = NULL;
14509
14510 ENTER();
14511
14512 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14513 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14514
14515 if (NULL != roamProfile.pBssDesc)
14516 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014517 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14518 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014519
14520 if (NULL == bss)
14521 {
14522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14523 __func__);
14524 }
14525
14526 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14527 }
14528 else
14529 {
14530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14531 __func__);
14532 }
14533 return bss;
14534}
14535
14536/*
14537 * FUNCTION: wlan_hdd_cfg80211_update_bss
14538 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014539static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14540 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014541 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014542{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014543 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014544 tCsrScanResultInfo *pScanResult;
14545 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014546 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 tScanResultHandle pResult;
14548 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014549 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014550 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014551 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014552
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14554 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14555 NO_SESSION, pAdapter->sessionId));
14556
Wilson Yangf80a0542013-10-07 13:02:37 -070014557 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014558 ret = wlan_hdd_validate_context(pHddCtx);
14559 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014560 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014561 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014562 }
14563
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014564 if (pAdapter->request != NULL)
14565 {
14566 if ((pAdapter->request->n_ssids == 1)
14567 && (pAdapter->request->ssids != NULL)
14568 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14569 is_p2p_scan = true;
14570 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014571 /*
14572 * start getting scan results and populate cgf80211 BSS database
14573 */
14574 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14575
14576 /* no scan results */
14577 if (NULL == pResult)
14578 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14580 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014581 wlan_hdd_get_frame_logs(pAdapter,
14582 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014583 return status;
14584 }
14585
14586 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14587
14588 while (pScanResult)
14589 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014590 /*
14591 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14592 * entry already exists in bss data base of cfg80211 for that
14593 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14594 * bss entry instead of cfg80211_inform_bss, But this call expects
14595 * mgmt packet as input. As of now there is no possibility to get
14596 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014597 * ieee80211_mgmt(probe response) and passing to c
14598 * fg80211_inform_bss_frame.
14599 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014600 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14601 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14602 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014603 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14604 continue; //Skip the non p2p bss entries
14605 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014606 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14607 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014608
Jeff Johnson295189b2012-06-20 16:38:30 -070014609
14610 if (NULL == bss_status)
14611 {
14612 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014613 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 }
14615 else
14616 {
Yue Maf49ba872013-08-19 12:04:25 -070014617 cfg80211_put_bss(
14618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14619 wiphy,
14620#endif
14621 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014622 }
14623
14624 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14625 }
14626
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014627 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014628 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014629 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014630}
14631
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014632void
14633hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14634{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014635 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014636 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014637} /****** end hddPrintMacAddr() ******/
14638
14639void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014640hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014641{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014642 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014643 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014644 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14645 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14646 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014647} /****** end hddPrintPmkId() ******/
14648
14649//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14650//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14651
14652//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14653//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14654
14655#define dump_bssid(bssid) \
14656 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014657 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14658 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014659 }
14660
14661#define dump_pmkid(pMac, pmkid) \
14662 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014663 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14664 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014665 }
14666
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014667#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014668/*
14669 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14670 * This function is used to notify the supplicant of a new PMKSA candidate.
14671 */
14672int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014673 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014674 int index, bool preauth )
14675{
Jeff Johnsone7245742012-09-05 17:12:55 -070014676#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014677 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014678 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014679
14680 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014681 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014682
14683 if( NULL == pRoamInfo )
14684 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014685 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014686 return -EINVAL;
14687 }
14688
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014689 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14690 {
14691 dump_bssid(pRoamInfo->bssid);
14692 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014693 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014694 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014695#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014696 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014697}
14698#endif //FEATURE_WLAN_LFR
14699
Yue Maef608272013-04-08 23:09:17 -070014700#ifdef FEATURE_WLAN_LFR_METRICS
14701/*
14702 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14703 * 802.11r/LFR metrics reporting function to report preauth initiation
14704 *
14705 */
14706#define MAX_LFR_METRICS_EVENT_LENGTH 100
14707VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14708 tCsrRoamInfo *pRoamInfo)
14709{
14710 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14711 union iwreq_data wrqu;
14712
14713 ENTER();
14714
14715 if (NULL == pAdapter)
14716 {
14717 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14718 return VOS_STATUS_E_FAILURE;
14719 }
14720
14721 /* create the event */
14722 memset(&wrqu, 0, sizeof(wrqu));
14723 memset(metrics_notification, 0, sizeof(metrics_notification));
14724
14725 wrqu.data.pointer = metrics_notification;
14726 wrqu.data.length = scnprintf(metrics_notification,
14727 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14728 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14729
14730 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14731
14732 EXIT();
14733
14734 return VOS_STATUS_SUCCESS;
14735}
14736
14737/*
14738 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14739 * 802.11r/LFR metrics reporting function to report preauth completion
14740 * or failure
14741 */
14742VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14743 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14744{
14745 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14746 union iwreq_data wrqu;
14747
14748 ENTER();
14749
14750 if (NULL == pAdapter)
14751 {
14752 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14753 return VOS_STATUS_E_FAILURE;
14754 }
14755
14756 /* create the event */
14757 memset(&wrqu, 0, sizeof(wrqu));
14758 memset(metrics_notification, 0, sizeof(metrics_notification));
14759
14760 scnprintf(metrics_notification, sizeof(metrics_notification),
14761 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14762 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14763
14764 if (1 == preauth_status)
14765 strncat(metrics_notification, " TRUE", 5);
14766 else
14767 strncat(metrics_notification, " FALSE", 6);
14768
14769 wrqu.data.pointer = metrics_notification;
14770 wrqu.data.length = strlen(metrics_notification);
14771
14772 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14773
14774 EXIT();
14775
14776 return VOS_STATUS_SUCCESS;
14777}
14778
14779/*
14780 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14781 * 802.11r/LFR metrics reporting function to report handover initiation
14782 *
14783 */
14784VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14785 tCsrRoamInfo *pRoamInfo)
14786{
14787 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14788 union iwreq_data wrqu;
14789
14790 ENTER();
14791
14792 if (NULL == pAdapter)
14793 {
14794 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14795 return VOS_STATUS_E_FAILURE;
14796 }
14797
14798 /* create the event */
14799 memset(&wrqu, 0, sizeof(wrqu));
14800 memset(metrics_notification, 0, sizeof(metrics_notification));
14801
14802 wrqu.data.pointer = metrics_notification;
14803 wrqu.data.length = scnprintf(metrics_notification,
14804 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14805 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14806
14807 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14808
14809 EXIT();
14810
14811 return VOS_STATUS_SUCCESS;
14812}
14813#endif
14814
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014815
14816/**
14817 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14818 * @scan_req: scan request to be checked
14819 *
14820 * Return: true or false
14821 */
14822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14823static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14824 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014825 *scan_req, hdd_context_t
14826 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014827{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014828 if (!scan_req || !scan_req->wiphy ||
14829 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014830 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14831 return false;
14832 }
14833 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14834 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14835 return false;
14836 }
14837 return true;
14838}
14839#else
14840static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14841 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014842 *scan_req, hdd_context_t
14843 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014844{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014845 if (!scan_req || !scan_req->wiphy ||
14846 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014847 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14848 return false;
14849 }
14850 return true;
14851}
14852#endif
14853
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014854#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14855/**
14856 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14857 * @adapter: Pointer to the adapter
14858 * @req : Scan request
14859 * @aborted : true scan aborted false scan success
14860 *
14861 * This function notifies scan done to cfg80211
14862 *
14863 * Return: none
14864 */
14865static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14866 struct cfg80211_scan_request *req,
14867 bool aborted)
14868{
14869 struct cfg80211_scan_info info = {
14870 .aborted = aborted
14871 };
14872
14873 if (adapter->dev->flags & IFF_UP)
14874 cfg80211_scan_done(req, &info);
14875 else
14876 hddLog(LOGW,
14877 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14878}
14879#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14880/**
14881 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14882 * @adapter: Pointer to the adapter
14883 * @req : Scan request
14884 * @aborted : true scan aborted false scan success
14885 *
14886 * This function notifies scan done to cfg80211
14887 *
14888 * Return: none
14889 */
14890static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14891 struct cfg80211_scan_request *req,
14892 bool aborted)
14893{
14894 if (adapter->dev->flags & IFF_UP)
14895 cfg80211_scan_done(req, aborted);
14896 else
14897 hddLog(LOGW,
14898 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14899}
14900#else
14901/**
14902 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14903 * @adapter: Pointer to the adapter
14904 * @req : Scan request
14905 * @aborted : true scan aborted false scan success
14906 *
14907 * This function notifies scan done to cfg80211
14908 *
14909 * Return: none
14910 */
14911static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14912 struct cfg80211_scan_request *req,
14913 bool aborted)
14914{
14915 cfg80211_scan_done(req, aborted);
14916}
14917#endif
14918
Mukul Sharmab392b642017-08-17 17:45:29 +053014919#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014920/*
14921 * FUNCTION: hdd_cfg80211_scan_done_callback
14922 * scanning callback function, called after finishing scan
14923 *
14924 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014925static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014926 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14927{
14928 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014929 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014931 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 struct cfg80211_scan_request *req = NULL;
14933 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014934 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014935 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014936 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014937
14938 ENTER();
14939
c_manjee1b4ab9a2016-10-26 11:36:55 +053014940 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14941 !pAdapter->dev) {
14942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14943 return 0;
14944 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014945 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014946 if (NULL == pHddCtx) {
14947 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014948 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014949 }
14950
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014951#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014952 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014953 {
14954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014955 }
14956#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014957 pScanInfo = &pHddCtx->scan_info;
14958
Jeff Johnson295189b2012-06-20 16:38:30 -070014959 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014960 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014961 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 __func__, halHandle, pContext, (int) scanId, (int) status);
14963
Kiet Lamac06e2c2013-10-23 16:25:07 +053014964 pScanInfo->mScanPendingCounter = 0;
14965
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014967 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014968 &pScanInfo->scan_req_completion_event,
14969 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014970 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014972 hddLog(VOS_TRACE_LEVEL_ERROR,
14973 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014974 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014975 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 }
14977
Yue Maef608272013-04-08 23:09:17 -070014978 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 {
14980 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014981 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 }
14983
14984 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014985 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 {
14987 hddLog(VOS_TRACE_LEVEL_INFO,
14988 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014989 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 (int) scanId);
14991 }
14992
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014993#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014994 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014995#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014996 {
14997 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14998 pAdapter);
14999 if (0 > ret)
15000 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053015001 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015002
Jeff Johnson295189b2012-06-20 16:38:30 -070015003 /* If any client wait scan result through WEXT
15004 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015005 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 {
15007 /* The other scan request waiting for current scan finish
15008 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015009 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070015010 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015011 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070015012 }
15013 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015014 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070015015 {
15016 struct net_device *dev = pAdapter->dev;
15017 union iwreq_data wrqu;
15018 int we_event;
15019 char *msg;
15020
15021 memset(&wrqu, '\0', sizeof(wrqu));
15022 we_event = SIOCGIWSCAN;
15023 msg = NULL;
15024 wireless_send_event(dev, we_event, &wrqu, msg);
15025 }
15026 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015027 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015028
15029 /* Get the Scan Req */
15030 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053015031 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015032
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015033 /* Scan is no longer pending */
15034 pScanInfo->mScanPending = VOS_FALSE;
15035
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053015036 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070015037 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015038#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015040 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015041#endif
15042
15043 if (pAdapter->dev) {
15044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15045 pAdapter->dev->name);
15046 }
mukul sharmae7041822015-12-03 15:09:21 +053015047 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015048 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015049 }
15050
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015051 /* last_scan_timestamp is used to decide if new scan
15052 * is needed or not on station interface. If last station
15053 * scan time and new station scan time is less then
15054 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015055 * Also only last_scan_timestamp is updated here last_scan_channellist
15056 * is updated on receiving scan request itself to make sure kernel
15057 * allocated scan request(scan_req) object is not dereferenced here,
15058 * because interface down, where kernel frees scan_req, may happen any
15059 * time while driver is processing scan_done_callback. So it's better
15060 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015061 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015062 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15063 if (status == eCSR_SCAN_SUCCESS)
15064 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15065 else {
15066 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15067 sizeof(pHddCtx->scan_info.last_scan_channelList));
15068 pHddCtx->scan_info.last_scan_numChannels = 0;
15069 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015070 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015071 }
15072
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015073 /*
15074 * cfg80211_scan_done informing NL80211 about completion
15075 * of scanning
15076 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015077 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15078 {
15079 aborted = true;
15080 }
mukul sharmae7041822015-12-03 15:09:21 +053015081
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015083 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15084 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015085#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015086 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015087
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015088 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015089
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015090allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015091 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15092 ) && (pHddCtx->spoofMacAddr.isEnabled
15093 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015094 /* Generate new random mac addr for next scan */
15095 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015096
15097 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15098 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015099 }
15100
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015101 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015102 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015103
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015104 /* Acquire wakelock to handle the case where APP's tries to suspend
15105 * immediatly after the driver gets connect request(i.e after scan)
15106 * from supplicant, this result in app's is suspending and not able
15107 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015108 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015109
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015110#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015111 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015112#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015113#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015114 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015115#endif
15116
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 EXIT();
15118 return 0;
15119}
15120
15121/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015122 * FUNCTION: hdd_isConnectionInProgress
15123 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015124 *
15125 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015126v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15127 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015128{
15129 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15130 hdd_station_ctx_t *pHddStaCtx = NULL;
15131 hdd_adapter_t *pAdapter = NULL;
15132 VOS_STATUS status = 0;
15133 v_U8_t staId = 0;
15134 v_U8_t *staMac = NULL;
15135
15136 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15137
15138 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15139 {
15140 pAdapter = pAdapterNode->pAdapter;
15141
15142 if( pAdapter )
15143 {
15144 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015145 "%s: Adapter with device mode %s (%d) exists",
15146 __func__, hdd_device_modetoString(pAdapter->device_mode),
15147 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015148 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015149 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15150 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15151 (eConnectionState_Connecting ==
15152 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15153 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015154 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015155 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015156 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015157 if (session_id && reason)
15158 {
15159 *session_id = pAdapter->sessionId;
15160 *reason = eHDD_CONNECTION_IN_PROGRESS;
15161 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015162 return VOS_TRUE;
15163 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015164 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015165 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015166 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015167 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015168 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015169 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015170 if (session_id && reason)
15171 {
15172 *session_id = pAdapter->sessionId;
15173 *reason = eHDD_REASSOC_IN_PROGRESS;
15174 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015175 return VOS_TRUE;
15176 }
15177 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015178 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15179 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015180 {
15181 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15182 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015183 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15184 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015185 {
15186 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015187 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015188 "%s: client " MAC_ADDRESS_STR
15189 " is in the middle of WPS/EAPOL exchange.", __func__,
15190 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015191 if (session_id && reason)
15192 {
15193 *session_id = pAdapter->sessionId;
15194 *reason = eHDD_EAPOL_IN_PROGRESS;
15195 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015196 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015197 }
15198 }
15199 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15200 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15201 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015202 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15203 ptSapContext pSapCtx = NULL;
15204 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15205 if(pSapCtx == NULL){
15206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15207 FL("psapCtx is NULL"));
15208 return VOS_FALSE;
15209 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015210 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15211 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015212 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15213 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015214 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015215 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015216
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015217 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015218 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15219 "middle of WPS/EAPOL exchange.", __func__,
15220 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015221 if (session_id && reason)
15222 {
15223 *session_id = pAdapter->sessionId;
15224 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15225 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015226 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015227 }
15228 }
15229 }
15230 }
15231 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15232 pAdapterNode = pNext;
15233 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015234 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015235}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015236
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015237/**
15238 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15239 * to the Scan request
15240 * @scanRequest: Pointer to the csr scan request
15241 * @request: Pointer to the scan request from supplicant
15242 *
15243 * Return: None
15244 */
15245#ifdef CFG80211_SCAN_BSSID
15246static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15247 struct cfg80211_scan_request *request)
15248{
15249 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15250}
15251#else
15252static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15253 struct cfg80211_scan_request *request)
15254{
15255}
15256#endif
15257
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015258/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015259 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 * this scan respond to scan trigger and update cfg80211 scan database
15261 * later, scan dump command can be used to recieve scan results
15262 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015263int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015264#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15265 struct net_device *dev,
15266#endif
15267 struct cfg80211_scan_request *request)
15268{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015269 hdd_adapter_t *pAdapter = NULL;
15270 hdd_context_t *pHddCtx = NULL;
15271 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015272 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015273 tCsrScanRequest scanRequest;
15274 tANI_U8 *channelList = NULL, i;
15275 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015276 int status;
15277 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015278 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015279 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015280 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015281 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015282 v_U8_t curr_session_id;
15283 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015284
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15286 struct net_device *dev = NULL;
15287 if (NULL == request)
15288 {
15289 hddLog(VOS_TRACE_LEVEL_ERROR,
15290 "%s: scan req param null", __func__);
15291 return -EINVAL;
15292 }
15293 dev = request->wdev->netdev;
15294#endif
15295
15296 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15297 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15298 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15299
Jeff Johnson295189b2012-06-20 16:38:30 -070015300 ENTER();
15301
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015302 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15303 __func__, hdd_device_modetoString(pAdapter->device_mode),
15304 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015305
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015306 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015307 if (0 != status)
15308 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015309 return status;
15310 }
15311
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015312 if (NULL == pwextBuf)
15313 {
15314 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15315 __func__);
15316 return -EIO;
15317 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015318 cfg_param = pHddCtx->cfg_ini;
15319 pScanInfo = &pHddCtx->scan_info;
15320
Jeff Johnson295189b2012-06-20 16:38:30 -070015321#ifdef WLAN_BTAMP_FEATURE
15322 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015323 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015324 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015325 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015326 "%s: No scanning when AMP is on", __func__);
15327 return -EOPNOTSUPP;
15328 }
15329#endif
15330 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015331 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015333 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015334 "%s: Not scanning on device_mode = %s (%d)",
15335 __func__, hdd_device_modetoString(pAdapter->device_mode),
15336 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015337 return -EOPNOTSUPP;
15338 }
15339
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015340 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15341 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15342 return -EOPNOTSUPP;
15343 }
15344
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 if (TRUE == pScanInfo->mScanPending)
15346 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015347 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15348 {
15349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15350 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015351 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 }
15353
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015354 // Don't allow scan if PNO scan is going on.
15355 if (pHddCtx->isPnoEnable)
15356 {
15357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15358 FL("pno scan in progress"));
15359 return -EBUSY;
15360 }
15361
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015362 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015363 //Channel and action frame is pending
15364 //Otherwise Cancel Remain On Channel and allow Scan
15365 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015366 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015367 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015369 return -EBUSY;
15370 }
15371
Jeff Johnson295189b2012-06-20 16:38:30 -070015372 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15373 {
15374 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015375 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015376 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015377 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015378 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15379 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015380 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015381 "%s: MAX TM Level Scan not allowed", __func__);
15382 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015383 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015384 }
15385 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15386
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015387 /* Check if scan is allowed at this point of time.
15388 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015389 if (TRUE == pHddCtx->btCoexModeSet)
15390 {
15391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15392 FL("BTCoex Mode operation in progress"));
15393 return -EBUSY;
15394 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015395 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015396 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015397
15398 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15399 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15400 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015401 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15402 pHddCtx->last_scan_reject_reason != curr_reason ||
15403 !pHddCtx->last_scan_reject_timestamp)
15404 {
15405 pHddCtx->last_scan_reject_session_id = curr_session_id;
15406 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015407 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015408 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015409 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015410 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015411 else
15412 {
15413 pHddCtx->scan_reject_cnt++;
15414
Abhishek Singhe4b12562017-06-20 16:53:39 +053015415 if ((pHddCtx->scan_reject_cnt >=
15416 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015417 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015418 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015419 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015420 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015421 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015422 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015423 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015424 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015425 if (pHddCtx->cfg_ini->enableFatalEvent)
15426 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15427 WLAN_LOG_INDICATOR_HOST_DRIVER,
15428 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15429 FALSE, FALSE);
15430 else
15431 {
15432 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015433 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015434 }
15435 }
15436 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015437 return -EBUSY;
15438 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015439 pHddCtx->last_scan_reject_timestamp = 0;
15440 pHddCtx->last_scan_reject_session_id = 0xFF;
15441 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015442 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015443
Jeff Johnson295189b2012-06-20 16:38:30 -070015444 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15445
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015446 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15447 * Becasue of this, driver is assuming that this is not wildcard scan and so
15448 * is not aging out the scan results.
15449 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015450 if ((request->ssids) && (request->n_ssids == 1) &&
15451 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015452 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015453 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015454
15455 if ((request->ssids) && (0 < request->n_ssids))
15456 {
15457 tCsrSSIDInfo *SsidInfo;
15458 int j;
15459 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15460 /* Allocate num_ssid tCsrSSIDInfo structure */
15461 SsidInfo = scanRequest.SSIDs.SSIDList =
15462 ( tCsrSSIDInfo *)vos_mem_malloc(
15463 request->n_ssids*sizeof(tCsrSSIDInfo));
15464
15465 if(NULL == scanRequest.SSIDs.SSIDList)
15466 {
15467 hddLog(VOS_TRACE_LEVEL_ERROR,
15468 "%s: memory alloc failed SSIDInfo buffer", __func__);
15469 return -ENOMEM;
15470 }
15471
15472 /* copy all the ssid's and their length */
15473 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15474 {
15475 /* get the ssid length */
15476 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15477 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15478 SsidInfo->SSID.length);
15479 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15480 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15481 j, SsidInfo->SSID.ssId);
15482 }
15483 /* set the scan type to active */
15484 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15485 }
15486 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015487 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15489 TRACE_CODE_HDD_CFG80211_SCAN,
15490 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015491 /* set the scan type to active */
15492 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015493 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015494 else
15495 {
15496 /*Set the scan type to default type, in this case it is ACTIVE*/
15497 scanRequest.scanType = pScanInfo->scan_mode;
15498 }
15499 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15500 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015501
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015502 csr_scan_request_assign_bssid(&scanRequest, request);
15503
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 /* set BSSType to default type */
15505 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15506
15507 /*TODO: scan the requested channels only*/
15508
15509 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015510 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015511 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015512 hddLog(VOS_TRACE_LEVEL_WARN,
15513 "No of Scan Channels exceeded limit: %d", request->n_channels);
15514 request->n_channels = MAX_CHANNEL;
15515 }
15516
15517 hddLog(VOS_TRACE_LEVEL_INFO,
15518 "No of Scan Channels: %d", request->n_channels);
15519
15520
15521 if( request->n_channels )
15522 {
15523 char chList [(request->n_channels*5)+1];
15524 int len;
15525 channelList = vos_mem_malloc( request->n_channels );
15526 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015527 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015528 hddLog(VOS_TRACE_LEVEL_ERROR,
15529 "%s: memory alloc failed channelList", __func__);
15530 status = -ENOMEM;
15531 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015532 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015533
15534 for( i = 0, len = 0; i < request->n_channels ; i++ )
15535 {
15536 channelList[i] = request->channels[i]->hw_value;
15537 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15538 }
15539
Nirav Shah20ac06f2013-12-12 18:14:06 +053015540 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015541 "Channel-List: %s ", chList);
15542 }
c_hpothu53512302014-04-15 18:49:53 +053015543
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015544 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15545 scanRequest.ChannelInfo.ChannelList = channelList;
15546
15547 /* set requestType to full scan */
15548 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15549
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015550 /* if there is back to back scan happening in driver with in
15551 * nDeferScanTimeInterval interval driver should defer new scan request
15552 * and should provide last cached scan results instead of new channel list.
15553 * This rule is not applicable if scan is p2p scan.
15554 * This condition will work only in case when last request no of channels
15555 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015556 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015557 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015558 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015559
Sushant Kaushik86592172015-04-27 16:35:03 +053015560 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15561 /* if wps ie is NULL , then only defer scan */
15562 if ( pWpsIe == NULL &&
15563 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015564 {
15565 if ( pScanInfo->last_scan_timestamp !=0 &&
15566 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15567 {
15568 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15569 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15570 vos_mem_compare(pScanInfo->last_scan_channelList,
15571 channelList, pScanInfo->last_scan_numChannels))
15572 {
15573 hddLog(VOS_TRACE_LEVEL_WARN,
15574 " New and old station scan time differ is less then %u",
15575 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15576
15577 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015578 pAdapter);
15579
Agarwal Ashish57e84372014-12-05 18:26:53 +053015580 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015581 "Return old cached scan as all channels and no of channels are same");
15582
Agarwal Ashish57e84372014-12-05 18:26:53 +053015583 if (0 > ret)
15584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015585
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015586 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015587
15588 status = eHAL_STATUS_SUCCESS;
15589 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015590 }
15591 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015592 }
15593
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015594 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15595 * search (Flush on both full scan and social scan but not on single
15596 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15597 */
15598
15599 /* Supplicant does single channel scan after 8-way handshake
15600 * and in that case driver shoudnt flush scan results. If
15601 * driver flushes the scan results here and unfortunately if
15602 * the AP doesnt respond to our probe req then association
15603 * fails which is not desired
15604 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015605 if ((request->n_ssids == 1)
15606 && (request->ssids != NULL)
15607 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15608 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015609
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015610 if( is_p2p_scan ||
15611 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015612 {
15613 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15614 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15615 pAdapter->sessionId );
15616 }
15617
15618 if( request->ie_len )
15619 {
15620 /* save this for future association (join requires this) */
15621 /*TODO: Array needs to be converted to dynamic allocation,
15622 * as multiple ie.s can be sent in cfg80211_scan_request structure
15623 * CR 597966
15624 */
15625 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15626 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15627 pScanInfo->scanAddIE.length = request->ie_len;
15628
15629 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15630 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15631 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015632 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015633 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015635 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15636 memcpy( pwextBuf->roamProfile.addIEScan,
15637 request->ie, request->ie_len);
15638 }
15639 else
15640 {
15641 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15642 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015643 }
15644
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015645 }
15646 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15647 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15648
15649 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15650 request->ie_len);
15651 if (pP2pIe != NULL)
15652 {
15653#ifdef WLAN_FEATURE_P2P_DEBUG
15654 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15655 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15656 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015657 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015658 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15659 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15660 "Go nego completed to Connection is started");
15661 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15662 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015663 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015664 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15665 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015666 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015667 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15668 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15669 "Disconnected state to Connection is started");
15670 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15671 "for 4way Handshake");
15672 }
15673#endif
15674
15675 /* no_cck will be set during p2p find to disable 11b rates */
15676 if(TRUE == request->no_cck)
15677 {
15678 hddLog(VOS_TRACE_LEVEL_INFO,
15679 "%s: This is a P2P Search", __func__);
15680 scanRequest.p2pSearch = 1;
15681
15682 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015683 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015684 /* set requestType to P2P Discovery */
15685 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15686 }
15687
15688 /*
15689 Skip Dfs Channel in case of P2P Search
15690 if it is set in ini file
15691 */
15692 if(cfg_param->skipDfsChnlInP2pSearch)
15693 {
15694 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015695 }
15696 else
15697 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015698 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015699 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015700
Agarwal Ashish4f616132013-12-30 23:32:50 +053015701 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015702 }
15703 }
15704
15705 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15706
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015707#ifdef FEATURE_WLAN_TDLS
15708 /* if tdls disagree scan right now, return immediately.
15709 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15710 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15711 */
15712 status = wlan_hdd_tdls_scan_callback (pAdapter,
15713 wiphy,
15714#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15715 dev,
15716#endif
15717 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015718 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015719 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015720 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15722 "scan rejected %d", __func__, status);
15723 else
15724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15725 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015726 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015727 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015728 }
15729#endif
15730
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015731 /* acquire the wakelock to avoid the apps suspend during the scan. To
15732 * address the following issues.
15733 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15734 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15735 * for long time, this result in apps running at full power for long time.
15736 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15737 * be stuck in full power because of resume BMPS
15738 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015739 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015740
Nirav Shah20ac06f2013-12-12 18:14:06 +053015741 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15742 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015743 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15744 scanRequest.requestType, scanRequest.scanType,
15745 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015746 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15747
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015748 if (pHddCtx->spoofMacAddr.isEnabled &&
15749 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015750 {
15751 hddLog(VOS_TRACE_LEVEL_INFO,
15752 "%s: MAC Spoofing enabled for current scan", __func__);
15753 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15754 * to fill TxBds for probe request during current scan
15755 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015756 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015757 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015758
15759 if(status != VOS_STATUS_SUCCESS)
15760 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015761 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015762 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015763#ifdef FEATURE_WLAN_TDLS
15764 wlan_hdd_tdls_scan_done_callback(pAdapter);
15765#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015766 goto free_mem;
15767 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015768 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015769 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015770 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015771 pAdapter->sessionId, &scanRequest, &scanId,
15772 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015773
Jeff Johnson295189b2012-06-20 16:38:30 -070015774 if (eHAL_STATUS_SUCCESS != status)
15775 {
15776 hddLog(VOS_TRACE_LEVEL_ERROR,
15777 "%s: sme_ScanRequest returned error %d", __func__, status);
15778 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015779 if(eHAL_STATUS_RESOURCES == status)
15780 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15782 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015783 status = -EBUSY;
15784 } else {
15785 status = -EIO;
15786 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015787 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015788
15789#ifdef FEATURE_WLAN_TDLS
15790 wlan_hdd_tdls_scan_done_callback(pAdapter);
15791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015792 goto free_mem;
15793 }
15794
15795 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015796 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015797 pAdapter->request = request;
15798 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015799 pScanInfo->no_cck = request->no_cck;
15800 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15801 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15802 pHddCtx->scan_info.last_scan_channelList[i] =
15803 request->channels[i]->hw_value;
15804 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015805
15806 complete(&pScanInfo->scan_req_completion_event);
15807
15808free_mem:
15809 if( scanRequest.SSIDs.SSIDList )
15810 {
15811 vos_mem_free(scanRequest.SSIDs.SSIDList);
15812 }
15813
15814 if( channelList )
15815 vos_mem_free( channelList );
15816
15817 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015818 return status;
15819}
15820
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015821int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15823 struct net_device *dev,
15824#endif
15825 struct cfg80211_scan_request *request)
15826{
15827 int ret;
15828
15829 vos_ssr_protect(__func__);
15830 ret = __wlan_hdd_cfg80211_scan(wiphy,
15831#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15832 dev,
15833#endif
15834 request);
15835 vos_ssr_unprotect(__func__);
15836
15837 return ret;
15838}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015839
15840void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15841{
15842 v_U8_t iniDot11Mode =
15843 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15844 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15845
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015846 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15847 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015848 switch ( iniDot11Mode )
15849 {
15850 case eHDD_DOT11_MODE_AUTO:
15851 case eHDD_DOT11_MODE_11ac:
15852 case eHDD_DOT11_MODE_11ac_ONLY:
15853#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015854 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15855 sme_IsFeatureSupportedByFW(DOT11AC) )
15856 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15857 else
15858 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015859#else
15860 hddDot11Mode = eHDD_DOT11_MODE_11n;
15861#endif
15862 break;
15863 case eHDD_DOT11_MODE_11n:
15864 case eHDD_DOT11_MODE_11n_ONLY:
15865 hddDot11Mode = eHDD_DOT11_MODE_11n;
15866 break;
15867 default:
15868 hddDot11Mode = iniDot11Mode;
15869 break;
15870 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015871#ifdef WLAN_FEATURE_AP_HT40_24G
15872 if (operationChannel > SIR_11B_CHANNEL_END)
15873#endif
15874 {
15875 /* This call decides required channel bonding mode */
15876 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015877 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015878 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015879 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015880}
15881
Jeff Johnson295189b2012-06-20 16:38:30 -070015882/*
15883 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015884 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015886int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015887 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15888 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015889{
15890 int status = 0;
15891 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015892 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015893 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015894 v_U32_t roamId;
15895 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015896 eCsrAuthType RSNAuthType;
15897
15898 ENTER();
15899
15900 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015901 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015902 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015903
15904 status = wlan_hdd_validate_context(pHddCtx);
15905 if (status)
15906 {
Yue Mae36e3552014-03-05 17:06:20 -080015907 return status;
15908 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015909
Jeff Johnson295189b2012-06-20 16:38:30 -070015910 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15911 {
15912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15913 return -EINVAL;
15914 }
15915
Nitesh Shah9b066282017-06-06 18:05:52 +053015916
Jeff Johnson295189b2012-06-20 16:38:30 -070015917 pRoamProfile = &pWextState->roamProfile;
15918
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015919 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015920 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015921 hdd_station_ctx_t *pHddStaCtx;
15922 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015923 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015924
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015925 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15926
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015927 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015928 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15929 {
15930 /*QoS not enabled in cfg file*/
15931 pRoamProfile->uapsd_mask = 0;
15932 }
15933 else
15934 {
15935 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015936 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015937 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15938 }
15939
15940 pRoamProfile->SSIDs.numOfSSIDs = 1;
15941 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15942 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015943 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015944 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15945 ssid, ssid_len);
15946
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015947 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15948 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15949
Jeff Johnson295189b2012-06-20 16:38:30 -070015950 if (bssid)
15951 {
15952 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015953 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015954 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015955 /* Save BSSID in seperate variable as well, as RoamProfile
15956 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015957 case of join failure we should send valid BSSID to supplicant
15958 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015959 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015960 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015961
Jeff Johnson295189b2012-06-20 16:38:30 -070015962 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015963 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015964 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015965 /* Store bssid_hint to use in the scan filter. */
15966 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15967 WNI_CFG_BSSID_LEN);
15968 /*
15969 * Save BSSID in seperate variable as well, as RoamProfile
15970 * BSSID is getting zeroed out in the association process. And in
15971 * case of join failure we should send valid BSSID to supplicant
15972 */
15973 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15974 WNI_CFG_BSSID_LEN);
15975 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15976 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015977 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015978
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015979
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015980 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15981 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015982 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15983 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015984 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015985 /*set gen ie*/
15986 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15987 /*set auth*/
15988 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15989 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015990#ifdef FEATURE_WLAN_WAPI
15991 if (pAdapter->wapi_info.nWapiMode)
15992 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015993 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015994 switch (pAdapter->wapi_info.wapiAuthMode)
15995 {
15996 case WAPI_AUTH_MODE_PSK:
15997 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015998 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015999 pAdapter->wapi_info.wapiAuthMode);
16000 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
16001 break;
16002 }
16003 case WAPI_AUTH_MODE_CERT:
16004 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016005 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016006 pAdapter->wapi_info.wapiAuthMode);
16007 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
16008 break;
16009 }
16010 } // End of switch
16011 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
16012 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
16013 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016014 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016015 pRoamProfile->AuthType.numEntries = 1;
16016 pRoamProfile->EncryptionType.numEntries = 1;
16017 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16018 pRoamProfile->mcEncryptionType.numEntries = 1;
16019 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16020 }
16021 }
16022#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016023#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016024 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016025 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
16026 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
16027 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016028 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
16029 sizeof (tSirGtkOffloadParams));
16030 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016031 }
16032#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016033 pRoamProfile->csrPersona = pAdapter->device_mode;
16034
Jeff Johnson32d95a32012-09-10 13:15:23 -070016035 if( operatingChannel )
16036 {
16037 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16038 pRoamProfile->ChannelInfo.numOfChannels = 1;
16039 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016040 else
16041 {
16042 pRoamProfile->ChannelInfo.ChannelList = NULL;
16043 pRoamProfile->ChannelInfo.numOfChannels = 0;
16044 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016045 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16046 {
16047 hdd_select_cbmode(pAdapter,operatingChannel);
16048 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016049
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016050 /*
16051 * Change conn_state to connecting before sme_RoamConnect(),
16052 * because sme_RoamConnect() has a direct path to call
16053 * hdd_smeRoamCallback(), which will change the conn_state
16054 * If direct path, conn_state will be accordingly changed
16055 * to NotConnected or Associated by either
16056 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16057 * in sme_RoamCallback()
16058 * if sme_RomConnect is to be queued,
16059 * Connecting state will remain until it is completed.
16060 * If connection state is not changed,
16061 * connection state will remain in eConnectionState_NotConnected state.
16062 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16063 * if conn state is eConnectionState_NotConnected.
16064 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16065 * informed of connect result indication which is an issue.
16066 */
16067
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016068 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16069 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016070 {
16071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016072 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016073 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16074 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016075 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16076 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016077 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016078
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016079 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016080 pAdapter->sessionId, pRoamProfile, &roamId);
16081
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016082 if ((eHAL_STATUS_SUCCESS != status) &&
16083 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16084 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016085
16086 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016087 hddLog(VOS_TRACE_LEVEL_ERROR,
16088 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16089 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016090 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016091 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016092 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016093 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016094
16095 pRoamProfile->ChannelInfo.ChannelList = NULL;
16096 pRoamProfile->ChannelInfo.numOfChannels = 0;
16097
Jeff Johnson295189b2012-06-20 16:38:30 -070016098 }
16099 else
16100 {
16101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16102 return -EINVAL;
16103 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016104 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 return status;
16106}
16107
16108/*
16109 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16110 * This function is used to set the authentication type (OPEN/SHARED).
16111 *
16112 */
16113static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16114 enum nl80211_auth_type auth_type)
16115{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016116 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016117 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16118
16119 ENTER();
16120
16121 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016122 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016123 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016124 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016125 hddLog(VOS_TRACE_LEVEL_INFO,
16126 "%s: set authentication type to AUTOSWITCH", __func__);
16127 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16128 break;
16129
16130 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016131#ifdef WLAN_FEATURE_VOWIFI_11R
16132 case NL80211_AUTHTYPE_FT:
16133#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016134 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 "%s: set authentication type to OPEN", __func__);
16136 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16137 break;
16138
16139 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016140 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 "%s: set authentication type to SHARED", __func__);
16142 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16143 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016144#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016145 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016146 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 "%s: set authentication type to CCKM WPA", __func__);
16148 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16149 break;
16150#endif
16151
16152
16153 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016154 hddLog(VOS_TRACE_LEVEL_ERROR,
16155 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016156 auth_type);
16157 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16158 return -EINVAL;
16159 }
16160
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016161 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016162 pHddStaCtx->conn_info.authType;
16163 return 0;
16164}
16165
16166/*
16167 * FUNCTION: wlan_hdd_set_akm_suite
16168 * This function is used to set the key mgmt type(PSK/8021x).
16169 *
16170 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016171static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 u32 key_mgmt
16173 )
16174{
16175 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16176 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016177 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016178#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016179#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016180#endif
16181#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016182#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016183#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016184 /*set key mgmt type*/
16185 switch(key_mgmt)
16186 {
16187 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016188 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016189#ifdef WLAN_FEATURE_VOWIFI_11R
16190 case WLAN_AKM_SUITE_FT_PSK:
16191#endif
16192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016193 __func__);
16194 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16195 break;
16196
16197 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016198 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016199#ifdef WLAN_FEATURE_VOWIFI_11R
16200 case WLAN_AKM_SUITE_FT_8021X:
16201#endif
16202 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 __func__);
16204 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16205 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016206#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016207#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16208#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16209 case WLAN_AKM_SUITE_CCKM:
16210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16211 __func__);
16212 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16213 break;
16214#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016215#ifndef WLAN_AKM_SUITE_OSEN
16216#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16217 case WLAN_AKM_SUITE_OSEN:
16218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16219 __func__);
16220 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16221 break;
16222#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016223
16224 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016226 __func__, key_mgmt);
16227 return -EINVAL;
16228
16229 }
16230 return 0;
16231}
16232
16233/*
16234 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016235 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016236 * (NONE/WEP40/WEP104/TKIP/CCMP).
16237 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016238static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16239 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016240 bool ucast
16241 )
16242{
16243 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016244 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016245 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16246
16247 ENTER();
16248
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016249 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016250 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016252 __func__, cipher);
16253 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16254 }
16255 else
16256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016257
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016259 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016260 {
16261 case IW_AUTH_CIPHER_NONE:
16262 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16263 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016264
Jeff Johnson295189b2012-06-20 16:38:30 -070016265 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016266 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016267 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016268
Jeff Johnson295189b2012-06-20 16:38:30 -070016269 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016270 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016271 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016272
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 case WLAN_CIPHER_SUITE_TKIP:
16274 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16275 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016276
Jeff Johnson295189b2012-06-20 16:38:30 -070016277 case WLAN_CIPHER_SUITE_CCMP:
16278 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16279 break;
16280#ifdef FEATURE_WLAN_WAPI
16281 case WLAN_CIPHER_SUITE_SMS4:
16282 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16283 break;
16284#endif
16285
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016286#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016287 case WLAN_CIPHER_SUITE_KRK:
16288 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16289 break;
16290#endif
16291 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016292 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016293 __func__, cipher);
16294 return -EOPNOTSUPP;
16295 }
16296 }
16297
16298 if (ucast)
16299 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016301 __func__, encryptionType);
16302 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16303 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016304 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016305 encryptionType;
16306 }
16307 else
16308 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016310 __func__, encryptionType);
16311 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16312 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16313 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16314 }
16315
16316 return 0;
16317}
16318
16319
16320/*
16321 * FUNCTION: wlan_hdd_cfg80211_set_ie
16322 * This function is used to parse WPA/RSN IE's.
16323 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016324int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16326 const u8 *ie,
16327#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016328 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016329#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016330 size_t ie_len
16331 )
16332{
16333 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016334#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16335 const u8 *genie = ie;
16336#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016337 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016338#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016339 v_U16_t remLen = ie_len;
16340#ifdef FEATURE_WLAN_WAPI
16341 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16342 u16 *tmp;
16343 v_U16_t akmsuiteCount;
16344 int *akmlist;
16345#endif
16346 ENTER();
16347
16348 /* clear previous assocAddIE */
16349 pWextState->assocAddIE.length = 0;
16350 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016351 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016352
16353 while (remLen >= 2)
16354 {
16355 v_U16_t eLen = 0;
16356 v_U8_t elementId;
16357 elementId = *genie++;
16358 eLen = *genie++;
16359 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016360
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016361 /* Sanity check on eLen */
16362 if (eLen > remLen) {
16363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16364 __func__, eLen, elementId);
16365 VOS_ASSERT(0);
16366 return -EINVAL;
16367 }
16368
Arif Hussain6d2a3322013-11-17 19:50:10 -080016369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016370 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016371
16372 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016373 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016374 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016375 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 -070016376 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016377 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016378 "%s: Invalid WPA IE", __func__);
16379 return -EINVAL;
16380 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016381 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016382 {
16383 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016384 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016385 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016386
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016387 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016388 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016389 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16390 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016391 VOS_ASSERT(0);
16392 return -ENOMEM;
16393 }
16394 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16395 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16396 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016397
Jeff Johnson295189b2012-06-20 16:38:30 -070016398 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16399 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16400 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16401 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016402 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16403 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016404 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16405 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16406 __func__, eLen);
16407 VOS_ASSERT(0);
16408 return -EINVAL;
16409 }
16410
Jeff Johnson295189b2012-06-20 16:38:30 -070016411 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16412 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16413 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16414 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16415 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16416 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016417 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016418 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016419 {
16420 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016421 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016422 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016423
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016424 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016425 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016426 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16427 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 VOS_ASSERT(0);
16429 return -ENOMEM;
16430 }
16431 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16432 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16433 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016434
Jeff Johnson295189b2012-06-20 16:38:30 -070016435 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16436 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16437 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016438#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016439 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16440 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 /*Consider WFD IE, only for P2P Client */
16442 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16443 {
16444 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016445 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016446 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016447
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016448 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016449 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016450 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16451 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016452 VOS_ASSERT(0);
16453 return -ENOMEM;
16454 }
16455 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16456 // WPS IE + P2P IE + WFD IE
16457 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16458 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016459
Jeff Johnson295189b2012-06-20 16:38:30 -070016460 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16461 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16462 }
16463#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016464 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016465 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016466 HS20_OUI_TYPE_SIZE)) )
16467 {
16468 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016469 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016470 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016471
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016472 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016473 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016474 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16475 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016476 VOS_ASSERT(0);
16477 return -ENOMEM;
16478 }
16479 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16480 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016481
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016482 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16483 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16484 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016485 /* Appending OSEN Information Element in Assiciation Request */
16486 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16487 OSEN_OUI_TYPE_SIZE)) )
16488 {
16489 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16490 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16491 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016492
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016493 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016494 {
16495 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16496 "Need bigger buffer space");
16497 VOS_ASSERT(0);
16498 return -ENOMEM;
16499 }
16500 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16501 pWextState->assocAddIE.length += eLen + 2;
16502
16503 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16504 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16505 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16506 }
16507
Abhishek Singh4322e622015-06-10 15:42:54 +053016508 /* Update only for WPA IE */
16509 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16510 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016511
16512 /* populating as ADDIE in beacon frames */
16513 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016514 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016515 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16516 {
16517 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16518 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16519 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16520 {
16521 hddLog(LOGE,
16522 "Coldn't pass "
16523 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16524 }
16525 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16526 else
16527 hddLog(LOGE,
16528 "Could not pass on "
16529 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16530
16531 /* IBSS mode doesn't contain params->proberesp_ies still
16532 beaconIE's need to be populated in probe response frames */
16533 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16534 {
16535 u16 rem_probe_resp_ie_len = eLen + 2;
16536 u8 probe_rsp_ie_len[3] = {0};
16537 u8 counter = 0;
16538
16539 /* Check Probe Resp Length if it is greater then 255 then
16540 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16541 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16542 not able Store More then 255 bytes into One Variable */
16543
16544 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16545 {
16546 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16547 {
16548 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16549 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16550 }
16551 else
16552 {
16553 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16554 rem_probe_resp_ie_len = 0;
16555 }
16556 }
16557
16558 rem_probe_resp_ie_len = 0;
16559
16560 if (probe_rsp_ie_len[0] > 0)
16561 {
16562 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16563 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16564 (tANI_U8*)(genie - 2),
16565 probe_rsp_ie_len[0], NULL,
16566 eANI_BOOLEAN_FALSE)
16567 == eHAL_STATUS_FAILURE)
16568 {
16569 hddLog(LOGE,
16570 "Could not pass"
16571 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16572 }
16573 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16574 }
16575
16576 if (probe_rsp_ie_len[1] > 0)
16577 {
16578 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16579 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16580 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16581 probe_rsp_ie_len[1], NULL,
16582 eANI_BOOLEAN_FALSE)
16583 == eHAL_STATUS_FAILURE)
16584 {
16585 hddLog(LOGE,
16586 "Could not pass"
16587 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16588 }
16589 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16590 }
16591
16592 if (probe_rsp_ie_len[2] > 0)
16593 {
16594 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16595 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16596 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16597 probe_rsp_ie_len[2], NULL,
16598 eANI_BOOLEAN_FALSE)
16599 == eHAL_STATUS_FAILURE)
16600 {
16601 hddLog(LOGE,
16602 "Could not pass"
16603 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16604 }
16605 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16606 }
16607
16608 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16609 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16610 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16611 {
16612 hddLog(LOGE,
16613 "Could not pass"
16614 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16615 }
16616 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016617 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016618 break;
16619 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016620 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16621 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16622 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16623 VOS_ASSERT(0);
16624 return -EINVAL;
16625 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016626 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16627 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16628 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16629 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16630 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16631 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016632
Abhishek Singhb16f3562016-01-20 11:08:32 +053016633 /* Appending extended capabilities with Interworking or
16634 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016635 *
16636 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016637 * interworkingService or bsstransition bit is set to 1.
16638 * Driver is only interested in interworkingService and
16639 * bsstransition capability from supplicant.
16640 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016641 * required from supplicat, it needs to be handled while
16642 * sending Assoc Req in LIM.
16643 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016644 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016645 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016646 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016647 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016648 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016649
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016650 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016651 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016652 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16653 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016654 VOS_ASSERT(0);
16655 return -ENOMEM;
16656 }
16657 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16658 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016659
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016660 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16661 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16662 break;
16663 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016664#ifdef FEATURE_WLAN_WAPI
16665 case WLAN_EID_WAPI:
16666 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016667 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016668 pAdapter->wapi_info.nWapiMode);
16669 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016670 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016671 akmsuiteCount = WPA_GET_LE16(tmp);
16672 tmp = tmp + 1;
16673 akmlist = (int *)(tmp);
16674 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16675 {
16676 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16677 }
16678 else
16679 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016680 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016681 VOS_ASSERT(0);
16682 return -EINVAL;
16683 }
16684
16685 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16686 {
16687 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016688 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016689 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016690 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016691 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016692 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016694 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016695 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16696 }
16697 break;
16698#endif
16699 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016700 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016701 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016702 /* when Unknown IE is received we should break and continue
16703 * to the next IE in the buffer instead we were returning
16704 * so changing this to break */
16705 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016706 }
16707 genie += eLen;
16708 remLen -= eLen;
16709 }
16710 EXIT();
16711 return 0;
16712}
16713
16714/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016715 * FUNCTION: hdd_isWPAIEPresent
16716 * Parse the received IE to find the WPA IE
16717 *
16718 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016719static bool hdd_isWPAIEPresent(
16720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16721 const u8 *ie,
16722#else
16723 u8 *ie,
16724#endif
16725 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016726{
16727 v_U8_t eLen = 0;
16728 v_U16_t remLen = ie_len;
16729 v_U8_t elementId = 0;
16730
16731 while (remLen >= 2)
16732 {
16733 elementId = *ie++;
16734 eLen = *ie++;
16735 remLen -= 2;
16736 if (eLen > remLen)
16737 {
16738 hddLog(VOS_TRACE_LEVEL_ERROR,
16739 "%s: IE length is wrong %d", __func__, eLen);
16740 return FALSE;
16741 }
16742 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16743 {
16744 /* OUI - 0x00 0X50 0XF2
16745 WPA Information Element - 0x01
16746 WPA version - 0x01*/
16747 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16748 return TRUE;
16749 }
16750 ie += eLen;
16751 remLen -= eLen;
16752 }
16753 return FALSE;
16754}
16755
16756/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016757 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016758 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016759 * parameters during connect operation.
16760 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016761int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016762 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016763 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016764{
16765 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016766 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016767 ENTER();
16768
16769 /*set wpa version*/
16770 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16771
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016772 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016773 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016774 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016775 {
16776 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16777 }
16778 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16779 {
16780 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16781 }
16782 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016783
16784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016785 pWextState->wpaVersion);
16786
16787 /*set authentication type*/
16788 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16789
16790 if (0 > status)
16791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016792 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016793 "%s: failed to set authentication type ", __func__);
16794 return status;
16795 }
16796
16797 /*set key mgmt type*/
16798 if (req->crypto.n_akm_suites)
16799 {
16800 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16801 if (0 > status)
16802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016804 __func__);
16805 return status;
16806 }
16807 }
16808
16809 /*set pairwise cipher type*/
16810 if (req->crypto.n_ciphers_pairwise)
16811 {
16812 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16813 req->crypto.ciphers_pairwise[0], true);
16814 if (0 > status)
16815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016816 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016817 "%s: failed to set unicast cipher type", __func__);
16818 return status;
16819 }
16820 }
16821 else
16822 {
16823 /*Reset previous cipher suite to none*/
16824 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16825 if (0 > status)
16826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016827 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016828 "%s: failed to set unicast cipher type", __func__);
16829 return status;
16830 }
16831 }
16832
16833 /*set group cipher type*/
16834 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16835 false);
16836
16837 if (0 > status)
16838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016840 __func__);
16841 return status;
16842 }
16843
Chet Lanctot186b5732013-03-18 10:26:30 -070016844#ifdef WLAN_FEATURE_11W
16845 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16846#endif
16847
Jeff Johnson295189b2012-06-20 16:38:30 -070016848 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16849 if (req->ie_len)
16850 {
16851 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16852 if ( 0 > status)
16853 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016855 __func__);
16856 return status;
16857 }
16858 }
16859
16860 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016861 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016862 {
16863 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16864 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16865 )
16866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016867 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016868 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016871 __func__);
16872 return -EOPNOTSUPP;
16873 }
16874 else
16875 {
16876 u8 key_len = req->key_len;
16877 u8 key_idx = req->key_idx;
16878
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016879 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016880 && (CSR_MAX_NUM_KEY > key_idx)
16881 )
16882 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016883 hddLog(VOS_TRACE_LEVEL_INFO,
16884 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016885 __func__, key_idx, key_len);
16886 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016887 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016888 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016889 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016890 (u8)key_len;
16891 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16892 }
16893 }
16894 }
16895 }
16896
16897 return status;
16898}
16899
16900/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016901 * FUNCTION: wlan_hdd_try_disconnect
16902 * This function is used to disconnect from previous
16903 * connection
16904 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016905int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016906{
16907 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016908 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016909 hdd_station_ctx_t *pHddStaCtx;
16910 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016911 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016912
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016913 ret = wlan_hdd_validate_context(pHddCtx);
16914 if (0 != ret)
16915 {
16916 return ret;
16917 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016918 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16919
16920 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16921
16922 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16923 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016924 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016925 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16926 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016927 /* Indicate disconnect to SME so that in-progress connection or preauth
16928 * can be aborted
16929 */
16930 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16931 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016932 spin_lock_bh(&pAdapter->lock_for_active_session);
16933 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16934 {
16935 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16936 }
16937 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016938 hdd_connSetConnectionState(pHddStaCtx,
16939 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016940 /* Issue disconnect to CSR */
16941 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016942 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016943 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016944 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16945 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16946 hddLog(LOG1,
16947 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16948 } else if ( 0 != status ) {
16949 hddLog(LOGE,
16950 FL("csrRoamDisconnect failure, returned %d"),
16951 (int)status );
16952 result = -EINVAL;
16953 goto disconnected;
16954 }
16955 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016956 &pAdapter->disconnect_comp_var,
16957 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016958 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16959 hddLog(LOGE,
16960 "%s: Failed to disconnect, timed out", __func__);
16961 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016962 }
16963 }
16964 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16965 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016966 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016967 &pAdapter->disconnect_comp_var,
16968 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016969 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016970 {
16971 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016972 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016973 }
16974 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016975disconnected:
16976 hddLog(LOG1,
16977 FL("Set HDD connState to eConnectionState_NotConnected"));
16978 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16979 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016980}
16981
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016982/**
16983 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16984 * @adapter: Pointer to the HDD adapter
16985 * @req: Pointer to the structure cfg_connect_params receieved from user space
16986 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053016987 * This function will start reassociation if prev_bssid is set and bssid/
16988 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016989 *
16990 * Return: success if reassociation is happening
16991 * Error code if reassociation is not permitted or not happening
16992 */
16993#ifdef CFG80211_CONNECT_PREV_BSSID
16994static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16995 struct cfg80211_connect_params *req)
16996{
16997 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053016998 const uint8_t *bssid = NULL;
16999 uint16_t channel = 0;
17000
17001 if (req->bssid)
17002 bssid = req->bssid;
17003 else if (req->bssid_hint)
17004 bssid = req->bssid_hint;
17005
17006 if (req->channel)
17007 channel = req->channel->hw_value;
17008 else if (req->channel_hint)
17009 channel = req->channel_hint->hw_value;
17010
17011 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017012 hddLog(VOS_TRACE_LEVEL_INFO,
17013 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053017014 channel, MAC_ADDR_ARRAY(bssid));
17015 status = hdd_reassoc(adapter, bssid, channel,
17016 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017017 }
17018 return status;
17019}
17020#else
17021static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17022 struct cfg80211_connect_params *req)
17023{
17024 return -EPERM;
17025}
17026#endif
17027
Abhishek Singhe3beee22017-07-31 15:35:40 +053017028/**
17029 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
17030 * connect in HT20 mode
17031 * @hdd_ctx: hdd context
17032 * @adapter: Pointer to the HDD adapter
17033 * @req: Pointer to the structure cfg_connect_params receieved from user space
17034 *
17035 * This function will check if supplicant has indicated to to connect in HT20
17036 * mode. this is currently applicable only for 2.4Ghz mode only.
17037 * if feature is enabled and supplicant indicate HT20 set
17038 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17039 *
17040 * Return: void
17041 */
17042#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17043static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17044 hdd_adapter_t *adapter,
17045 struct cfg80211_connect_params *req)
17046{
17047 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17048 tCsrRoamProfile *roam_profile;
17049
17050 roam_profile = &wext_state->roamProfile;
17051 roam_profile->force_24ghz_in_ht20 = false;
17052 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17053 !(req->ht_capa.cap_info &
17054 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17055 roam_profile->force_24ghz_in_ht20 = true;
17056
17057 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17058 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17059}
17060#else
17061static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17062 hdd_adapter_t *adapter,
17063 struct cfg80211_connect_params *req)
17064{
17065 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17066 tCsrRoamProfile *roam_profile;
17067
17068 roam_profile = &wext_state->roamProfile;
17069 roam_profile->force_24ghz_in_ht20 = false;
17070}
17071#endif
17072
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017073/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017074 * FUNCTION: __wlan_hdd_cfg80211_connect
17075 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017077static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017078 struct net_device *ndev,
17079 struct cfg80211_connect_params *req
17080 )
17081{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017082 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017083 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17085 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017086 const u8 *bssid_hint = req->bssid_hint;
17087#else
17088 const u8 *bssid_hint = NULL;
17089#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017091 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017092 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017093
17094 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017095
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17097 TRACE_CODE_HDD_CFG80211_CONNECT,
17098 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017099 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017100 "%s: device_mode = %s (%d)", __func__,
17101 hdd_device_modetoString(pAdapter->device_mode),
17102 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017104 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017105 if (!pHddCtx)
17106 {
17107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17108 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017109 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017110 }
17111
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017112 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017113 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017114 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017115 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017116 }
17117
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017118 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17119 return -EINVAL;
17120
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017121 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17122 if (0 == status)
17123 return status;
17124
Agarwal Ashish51325b52014-06-16 16:50:49 +053017125
Jeff Johnson295189b2012-06-20 16:38:30 -070017126#ifdef WLAN_BTAMP_FEATURE
17127 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017128 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017129 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017130 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017131 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017132 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017133 }
17134#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017135
17136 //If Device Mode is Station Concurrent Sessions Exit BMps
17137 //P2P Mode will be taken care in Open/close adapter
17138 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017139 (vos_concurrent_open_sessions_running())) {
17140 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17141 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017142 }
17143
17144 /*Try disconnecting if already in connected state*/
17145 status = wlan_hdd_try_disconnect(pAdapter);
17146 if ( 0 > status)
17147 {
17148 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17149 " connection"));
17150 return -EALREADY;
17151 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017152 /* Check for max concurrent connections after doing disconnect if any*/
17153 if (vos_max_concurrent_connections_reached()) {
17154 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17155 return -ECONNREFUSED;
17156 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017157
Jeff Johnson295189b2012-06-20 16:38:30 -070017158 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017159 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017160
17161 if ( 0 > status)
17162 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017164 __func__);
17165 return status;
17166 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017167
17168 if (pHddCtx->spoofMacAddr.isEnabled)
17169 {
17170 hddLog(VOS_TRACE_LEVEL_INFO,
17171 "%s: MAC Spoofing enabled ", __func__);
17172 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17173 * to fill TxBds for probe request during SSID scan which may happen
17174 * as part of connect command
17175 */
17176 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17177 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17178 if (status != VOS_STATUS_SUCCESS)
17179 return -ECONNREFUSED;
17180 }
17181
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017182 if (req->channel)
17183 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017184 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017185 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017186
17187 /* Abort if any scan is going on */
17188 status = wlan_hdd_scan_abort(pAdapter);
17189 if (0 != status)
17190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17191
Abhishek Singhe3beee22017-07-31 15:35:40 +053017192 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17193
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017194 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17195 req->ssid_len, req->bssid,
17196 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017197
Sushant Kaushikd7083982015-03-18 14:33:24 +053017198 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017199 {
17200 //ReEnable BMPS if disabled
17201 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17202 (NULL != pHddCtx))
17203 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017204 if (pHddCtx->hdd_wlan_suspended)
17205 {
17206 hdd_set_pwrparams(pHddCtx);
17207 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017208 //ReEnable Bmps and Imps back
17209 hdd_enable_bmps_imps(pHddCtx);
17210 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017212 return status;
17213 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017214 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017215 EXIT();
17216 return status;
17217}
17218
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017219static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17220 struct net_device *ndev,
17221 struct cfg80211_connect_params *req)
17222{
17223 int ret;
17224 vos_ssr_protect(__func__);
17225 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17226 vos_ssr_unprotect(__func__);
17227
17228 return ret;
17229}
Jeff Johnson295189b2012-06-20 16:38:30 -070017230
17231/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017232 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017233 * This function is used to issue a disconnect request to SME
17234 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017235static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017236 struct net_device *dev,
17237 u16 reason
17238 )
17239{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017241 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017242 tCsrRoamProfile *pRoamProfile;
17243 hdd_station_ctx_t *pHddStaCtx;
17244 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017245#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017246 tANI_U8 staIdx;
17247#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017248
Jeff Johnson295189b2012-06-20 16:38:30 -070017249 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017250
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017251 if (!pAdapter) {
17252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17253 return -EINVAL;
17254 }
17255
17256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17257 if (!pHddStaCtx) {
17258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17259 return -EINVAL;
17260 }
17261
17262 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17263 status = wlan_hdd_validate_context(pHddCtx);
17264 if (0 != status)
17265 {
17266 return status;
17267 }
17268
17269 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17270
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017271 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17272 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17273 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017274 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17275 __func__, hdd_device_modetoString(pAdapter->device_mode),
17276 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017277
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17279 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017280
Jeff Johnson295189b2012-06-20 16:38:30 -070017281 if (NULL != pRoamProfile)
17282 {
17283 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017284 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17285 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017286 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017287 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017288 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017289 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 switch(reason)
17291 {
17292 case WLAN_REASON_MIC_FAILURE:
17293 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17294 break;
17295
17296 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17297 case WLAN_REASON_DISASSOC_AP_BUSY:
17298 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17299 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17300 break;
17301
17302 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17303 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017304 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017305 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17306 break;
17307
Jeff Johnson295189b2012-06-20 16:38:30 -070017308 default:
17309 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17310 break;
17311 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017312 pScanInfo = &pHddCtx->scan_info;
17313 if (pScanInfo->mScanPending)
17314 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017315 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017316 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017317 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017318 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017319 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017320 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017321#ifdef FEATURE_WLAN_TDLS
17322 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017323 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017324 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017325 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17326 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017327 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017328 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017329 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017331 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017332 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017333 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017334 status = sme_DeleteTdlsPeerSta(
17335 WLAN_HDD_GET_HAL_CTX(pAdapter),
17336 pAdapter->sessionId,
17337 mac);
17338 if (status != eHAL_STATUS_SUCCESS) {
17339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17340 return -EPERM;
17341 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017342 }
17343 }
17344#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017345
17346 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17347 reasonCode,
17348 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017349 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17350 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 {
17352 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017353 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017354 __func__, (int)status );
17355 return -EINVAL;
17356 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017357 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017358 else
17359 {
17360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17361 "called while in %d state", __func__,
17362 pHddStaCtx->conn_info.connState);
17363 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 }
17365 else
17366 {
17367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17368 }
17369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017370 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017371 return status;
17372}
17373
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017374static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17375 struct net_device *dev,
17376 u16 reason
17377 )
17378{
17379 int ret;
17380 vos_ssr_protect(__func__);
17381 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17382 vos_ssr_unprotect(__func__);
17383
17384 return ret;
17385}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017386
Jeff Johnson295189b2012-06-20 16:38:30 -070017387/*
17388 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017389 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017390 * settings in IBSS mode.
17391 */
17392static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017393 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017394 struct cfg80211_ibss_params *params
17395 )
17396{
17397 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017398 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017399 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017400 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17401 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017402
Jeff Johnson295189b2012-06-20 16:38:30 -070017403 ENTER();
17404
17405 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017406 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017407
17408 if (params->ie_len && ( NULL != params->ie) )
17409 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017410 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17411 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017412 {
17413 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17414 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17415 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017416 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017417 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017418 tDot11fIEWPA dot11WPAIE;
17419 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017420 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017421
Wilson Yang00256342013-10-10 23:13:38 -070017422 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017423 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17424 params->ie_len, DOT11F_EID_WPA);
17425 if ( NULL != ie )
17426 {
17427 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017428
17429 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17430 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17431 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17432 return -EINVAL;
17433 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017434 // Unpack the WPA IE
17435 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017436 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017437 &ie[2+4],
17438 ie[1] - 4,
17439 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017440 if (DOT11F_FAILED(ret))
17441 {
17442 hddLog(LOGE,
17443 FL("unpack failed status:(0x%08x)"),
17444 ret);
17445 return -EINVAL;
17446 }
17447
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017448 /*Extract the multicast cipher, the encType for unicast
17449 cipher for wpa-none is none*/
17450 encryptionType =
17451 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17452 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017453 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017454
Jeff Johnson295189b2012-06-20 16:38:30 -070017455 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17456
17457 if (0 > status)
17458 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017460 __func__);
17461 return status;
17462 }
17463 }
17464
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017465 pWextState->roamProfile.AuthType.authType[0] =
17466 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017467 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017468 if (params->privacy)
17469 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017470 /* Security enabled IBSS, At this time there is no information available
17471 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017472 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017473 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017474 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017475 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017476 *enable privacy bit in beacons */
17477
17478 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17479 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017480 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17481 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017482 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17483 pWextState->roamProfile.EncryptionType.numEntries = 1;
17484 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017485 return status;
17486}
17487
17488/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017489 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017490 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017491 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017492static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017493 struct net_device *dev,
17494 struct cfg80211_ibss_params *params
17495 )
17496{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017497 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017498 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17499 tCsrRoamProfile *pRoamProfile;
17500 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017501 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17502 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017503 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017504
17505 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017506
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17508 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17509 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017510 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017511 "%s: device_mode = %s (%d)", __func__,
17512 hdd_device_modetoString(pAdapter->device_mode),
17513 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017514
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017515 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017516 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017517 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017518 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 }
17520
17521 if (NULL == pWextState)
17522 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017523 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017524 __func__);
17525 return -EIO;
17526 }
17527
Agarwal Ashish51325b52014-06-16 16:50:49 +053017528 if (vos_max_concurrent_connections_reached()) {
17529 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17530 return -ECONNREFUSED;
17531 }
17532
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017533 /*Try disconnecting if already in connected state*/
17534 status = wlan_hdd_try_disconnect(pAdapter);
17535 if ( 0 > status)
17536 {
17537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17538 " IBSS connection"));
17539 return -EALREADY;
17540 }
17541
Jeff Johnson295189b2012-06-20 16:38:30 -070017542 pRoamProfile = &pWextState->roamProfile;
17543
17544 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017546 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017547 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017548 return -EINVAL;
17549 }
17550
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017551 /* BSSID is provided by upper layers hence no need to AUTO generate */
17552 if (NULL != params->bssid) {
17553 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17554 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17555 hddLog (VOS_TRACE_LEVEL_ERROR,
17556 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17557 return -EIO;
17558 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017559 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017560 }
krunal sonie9002db2013-11-25 14:24:17 -080017561 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17562 {
17563 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17564 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17565 {
17566 hddLog (VOS_TRACE_LEVEL_ERROR,
17567 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17568 return -EIO;
17569 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017570
17571 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017572 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017573 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017574 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017575
Jeff Johnson295189b2012-06-20 16:38:30 -070017576 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017577 if (NULL !=
17578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17579 params->chandef.chan)
17580#else
17581 params->channel)
17582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017583 {
17584 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017585 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17586 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17587 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17588 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017589
17590 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017591 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017592 ieee80211_frequency_to_channel(
17593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17594 params->chandef.chan->center_freq);
17595#else
17596 params->channel->center_freq);
17597#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017598
17599 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17600 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017601 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17603 __func__);
17604 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017606
17607 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017608 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017609 if (channelNum == validChan[indx])
17610 {
17611 break;
17612 }
17613 }
17614 if (indx >= numChans)
17615 {
17616 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017617 __func__, channelNum);
17618 return -EINVAL;
17619 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017620 /* Set the Operational Channel */
17621 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17622 channelNum);
17623 pRoamProfile->ChannelInfo.numOfChannels = 1;
17624 pHddStaCtx->conn_info.operationChannel = channelNum;
17625 pRoamProfile->ChannelInfo.ChannelList =
17626 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017627 }
17628
17629 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017630 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017631 if (status < 0)
17632 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 __func__);
17635 return status;
17636 }
17637
17638 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017639 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017640 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017641 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017642
17643 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017645
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017646 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017647 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017648}
17649
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017650static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17651 struct net_device *dev,
17652 struct cfg80211_ibss_params *params
17653 )
17654{
17655 int ret = 0;
17656
17657 vos_ssr_protect(__func__);
17658 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17659 vos_ssr_unprotect(__func__);
17660
17661 return ret;
17662}
17663
Jeff Johnson295189b2012-06-20 16:38:30 -070017664/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017665 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017666 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017667 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017668static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017669 struct net_device *dev
17670 )
17671{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017673 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17674 tCsrRoamProfile *pRoamProfile;
17675 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017676 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017677 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017678#ifdef WLAN_FEATURE_RMC
17679 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17680#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017681
17682 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017683
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17685 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17686 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017687 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017688 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017689 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017690 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017691 }
17692
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17694 hdd_device_modetoString(pAdapter->device_mode),
17695 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017696 if (NULL == pWextState)
17697 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017698 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017699 __func__);
17700 return -EIO;
17701 }
17702
17703 pRoamProfile = &pWextState->roamProfile;
17704
17705 /* Issue disconnect only if interface type is set to IBSS */
17706 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017708 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017709 __func__);
17710 return -EINVAL;
17711 }
17712
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017713#ifdef WLAN_FEATURE_RMC
17714 /* Clearing add IE of beacon */
17715 if (ccmCfgSetStr(pHddCtx->hHal,
17716 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17717 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17718 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17719 {
17720 hddLog (VOS_TRACE_LEVEL_ERROR,
17721 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17722 return -EINVAL;
17723 }
17724 if (ccmCfgSetInt(pHddCtx->hHal,
17725 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17726 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17727 {
17728 hddLog (VOS_TRACE_LEVEL_ERROR,
17729 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17730 __func__);
17731 return -EINVAL;
17732 }
17733
17734 // Reset WNI_CFG_PROBE_RSP Flags
17735 wlan_hdd_reset_prob_rspies(pAdapter);
17736
17737 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17738 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17739 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17740 {
17741 hddLog (VOS_TRACE_LEVEL_ERROR,
17742 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17743 __func__);
17744 return -EINVAL;
17745 }
17746#endif
17747
Jeff Johnson295189b2012-06-20 16:38:30 -070017748 /* Issue Disconnect request */
17749 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017750 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17751 pAdapter->sessionId,
17752 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17753 if (!HAL_STATUS_SUCCESS(hal_status)) {
17754 hddLog(LOGE,
17755 FL("sme_RoamDisconnect failed hal_status(%d)"),
17756 hal_status);
17757 return -EAGAIN;
17758 }
17759 status = wait_for_completion_timeout(
17760 &pAdapter->disconnect_comp_var,
17761 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17762 if (!status) {
17763 hddLog(LOGE,
17764 FL("wait on disconnect_comp_var failed"));
17765 return -ETIMEDOUT;
17766 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017768 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017769 return 0;
17770}
17771
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017772static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17773 struct net_device *dev
17774 )
17775{
17776 int ret = 0;
17777
17778 vos_ssr_protect(__func__);
17779 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17780 vos_ssr_unprotect(__func__);
17781
17782 return ret;
17783}
17784
Jeff Johnson295189b2012-06-20 16:38:30 -070017785/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017786 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017787 * This function is used to set the phy parameters
17788 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17789 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017790static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017791 u32 changed)
17792{
17793 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17794 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017795 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017796
17797 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017798
17799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017800 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17801 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017802
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017804 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017806 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017807 }
17808
Jeff Johnson295189b2012-06-20 16:38:30 -070017809 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17810 {
17811 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17812 WNI_CFG_RTS_THRESHOLD_STAMAX :
17813 wiphy->rts_threshold;
17814
17815 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017816 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017818 hddLog(VOS_TRACE_LEVEL_ERROR,
17819 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017820 __func__, rts_threshold);
17821 return -EINVAL;
17822 }
17823
17824 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17825 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017826 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017828 hddLog(VOS_TRACE_LEVEL_ERROR,
17829 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017830 __func__, rts_threshold);
17831 return -EIO;
17832 }
17833
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017834 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017835 rts_threshold);
17836 }
17837
17838 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17839 {
17840 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17841 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17842 wiphy->frag_threshold;
17843
17844 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017845 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017846 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017847 hddLog(VOS_TRACE_LEVEL_ERROR,
17848 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017849 frag_threshold);
17850 return -EINVAL;
17851 }
17852
17853 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17854 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017855 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017856 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017857 hddLog(VOS_TRACE_LEVEL_ERROR,
17858 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017859 __func__, frag_threshold);
17860 return -EIO;
17861 }
17862
17863 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17864 frag_threshold);
17865 }
17866
17867 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17868 || (changed & WIPHY_PARAM_RETRY_LONG))
17869 {
17870 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17871 wiphy->retry_short :
17872 wiphy->retry_long;
17873
17874 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17875 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017878 __func__, retry_value);
17879 return -EINVAL;
17880 }
17881
17882 if (changed & WIPHY_PARAM_RETRY_SHORT)
17883 {
17884 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17885 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017886 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017888 hddLog(VOS_TRACE_LEVEL_ERROR,
17889 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017890 __func__, retry_value);
17891 return -EIO;
17892 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017893 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017894 __func__, retry_value);
17895 }
17896 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17897 {
17898 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17899 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017900 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017902 hddLog(VOS_TRACE_LEVEL_ERROR,
17903 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017904 __func__, retry_value);
17905 return -EIO;
17906 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017907 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017908 __func__, retry_value);
17909 }
17910 }
17911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017912 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017913 return 0;
17914}
17915
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017916static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17917 u32 changed)
17918{
17919 int ret;
17920
17921 vos_ssr_protect(__func__);
17922 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17923 vos_ssr_unprotect(__func__);
17924
17925 return ret;
17926}
17927
Jeff Johnson295189b2012-06-20 16:38:30 -070017928/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017929 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017930 * This function is used to set the txpower
17931 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017932static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017933#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17934 struct wireless_dev *wdev,
17935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017936#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017937 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017938#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017939 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017940#endif
17941 int dbm)
17942{
17943 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017944 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017945 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17946 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017947 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017948
17949 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017950
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017951 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17952 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17953 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017954 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017955 if (0 != status)
17956 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017957 return status;
17958 }
17959
17960 hHal = pHddCtx->hHal;
17961
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017962 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17963 dbm, ccmCfgSetCallback,
17964 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017965 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017966 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017967 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17968 return -EIO;
17969 }
17970
17971 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17972 dbm);
17973
17974 switch(type)
17975 {
17976 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17977 /* Fall through */
17978 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17979 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017981 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17982 __func__);
17983 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017984 }
17985 break;
17986 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017988 __func__);
17989 return -EOPNOTSUPP;
17990 break;
17991 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17993 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017994 return -EIO;
17995 }
17996
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017997 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017998 return 0;
17999}
18000
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018001static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
18002#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18003 struct wireless_dev *wdev,
18004#endif
18005#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18006 enum tx_power_setting type,
18007#else
18008 enum nl80211_tx_power_setting type,
18009#endif
18010 int dbm)
18011{
18012 int ret;
18013 vos_ssr_protect(__func__);
18014 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
18015#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18016 wdev,
18017#endif
18018#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18019 type,
18020#else
18021 type,
18022#endif
18023 dbm);
18024 vos_ssr_unprotect(__func__);
18025
18026 return ret;
18027}
18028
Jeff Johnson295189b2012-06-20 16:38:30 -070018029/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018030 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018031 * This function is used to read the txpower
18032 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018033static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018034#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18035 struct wireless_dev *wdev,
18036#endif
18037 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018038{
18039
18040 hdd_adapter_t *pAdapter;
18041 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018042 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018043
Jeff Johnsone7245742012-09-05 17:12:55 -070018044 ENTER();
18045
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018046 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018047 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018048 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018049 *dbm = 0;
18050 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018051 }
18052
Jeff Johnson295189b2012-06-20 16:38:30 -070018053 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18054 if (NULL == pAdapter)
18055 {
18056 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18057 return -ENOENT;
18058 }
18059
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018060 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18061 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18062 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018063 wlan_hdd_get_classAstats(pAdapter);
18064 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18065
Jeff Johnsone7245742012-09-05 17:12:55 -070018066 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018067 return 0;
18068}
18069
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018070static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18071#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18072 struct wireless_dev *wdev,
18073#endif
18074 int *dbm)
18075{
18076 int ret;
18077
18078 vos_ssr_protect(__func__);
18079 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18080#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18081 wdev,
18082#endif
18083 dbm);
18084 vos_ssr_unprotect(__func__);
18085
18086 return ret;
18087}
18088
Dustin Brown8c1d4092017-07-28 18:08:01 +053018089/*
18090 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18091 * @stats: summary stats to use as a source
18092 * @info: kernel station_info struct to use as a destination
18093 *
18094 * Return: None
18095 */
18096static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18097 struct station_info *info)
18098{
18099 int i;
18100
18101 info->rx_packets = stats->rx_frm_cnt;
18102 info->tx_packets = 0;
18103 info->tx_retries = 0;
18104 info->tx_failed = 0;
18105
18106 for (i = 0; i < 4; ++i) {
18107 info->tx_packets += stats->tx_frm_cnt[i];
18108 info->tx_retries += stats->multiple_retry_cnt[i];
18109 info->tx_failed += stats->fail_cnt[i];
18110 }
18111
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018112#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18113 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018114 info->filled |= STATION_INFO_TX_PACKETS |
18115 STATION_INFO_TX_RETRIES |
18116 STATION_INFO_TX_FAILED |
18117 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018118#else
18119 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18120 BIT(NL80211_STA_INFO_TX_RETRIES) |
18121 BIT(NL80211_STA_INFO_TX_FAILED) |
18122 BIT(NL80211_STA_INFO_RX_PACKETS);
18123#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018124}
18125
18126/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018127 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18128 * @adapter: sap adapter pointer
18129 * @staid: station id of the client
18130 * @rssi: rssi value to fill
18131 *
18132 * Return: None
18133 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018134void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018135wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18136{
18137 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18138
18139 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18140}
18141
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018142#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18143 !defined(WITH_BACKPORTS)
18144static inline void wlan_hdd_fill_station_info_signal(struct station_info
18145 *sinfo)
18146{
18147 sinfo->filled |= STATION_INFO_SIGNAL;
18148}
18149#else
18150static inline void wlan_hdd_fill_station_info_signal(struct station_info
18151 *sinfo)
18152{
18153 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18154}
18155#endif
18156
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018157/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018158 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18159 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018160 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018161 * @info: kernel station_info struct to populate
18162 *
18163 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18164 * support "station dump" and "station get" for SAP vdevs, even though they
18165 * aren't technically stations.
18166 *
18167 * Return: errno
18168 */
18169static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018170wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18172 const u8* mac,
18173#else
18174 u8* mac,
18175#endif
18176 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018177{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018178 v_MACADDR_t *peerMacAddr;
18179 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018180 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018181 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018182
18183 status = wlan_hdd_get_station_stats(adapter);
18184 if (!VOS_IS_STATUS_SUCCESS(status)) {
18185 hddLog(VOS_TRACE_LEVEL_ERROR,
18186 "Failed to get SAP stats; status:%d", status);
18187 return 0;
18188 }
18189
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018190 peerMacAddr = (v_MACADDR_t *)mac;
18191 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18192 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18193 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18194
18195 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18196 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018197 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018198 }
18199
Dustin Brown8c1d4092017-07-28 18:08:01 +053018200 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18201
18202 return 0;
18203}
18204
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018205static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18207 const u8* mac,
18208#else
18209 u8* mac,
18210#endif
18211 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018212{
18213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18214 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18215 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018216 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018217
18218 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18219 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018220
18221 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18222 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18223 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18224 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18225 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18226 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18227 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018228 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018229 tANI_U16 myRate;
18230 tANI_U16 currentRate = 0;
18231 tANI_U8 maxSpeedMCS = 0;
18232 tANI_U8 maxMCSIdx = 0;
18233 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018234 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018235 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018236 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018237
Leo Chang6f8870f2013-03-26 18:11:36 -070018238#ifdef WLAN_FEATURE_11AC
18239 tANI_U32 vht_mcs_map;
18240 eDataRate11ACMaxMcs vhtMaxMcs;
18241#endif /* WLAN_FEATURE_11AC */
18242
Jeff Johnsone7245742012-09-05 17:12:55 -070018243 ENTER();
18244
Dustin Brown8c1d4092017-07-28 18:08:01 +053018245 status = wlan_hdd_validate_context(pHddCtx);
18246 if (0 != status)
18247 {
18248 return status;
18249 }
18250
18251 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018252 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018253
Jeff Johnson295189b2012-06-20 16:38:30 -070018254 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18255 (0 == ssidlen))
18256 {
18257 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18258 " Invalid ssidlen, %d", __func__, ssidlen);
18259 /*To keep GUI happy*/
18260 return 0;
18261 }
18262
Mukul Sharma811205f2014-07-09 21:07:30 +053018263 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18264 {
18265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18266 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018267 /* return a cached value */
18268 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018269 return 0;
18270 }
18271
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018272 wlan_hdd_get_station_stats(pAdapter);
18273 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018274
Kiet Lam3b17fc82013-09-27 05:24:08 +053018275 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018276 wlan_hdd_get_snr(pAdapter, &snr);
18277 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018278 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018279 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018280 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018281 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018282
c_hpothu09f19542014-05-30 21:53:31 +053018283 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018284 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18285 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018286 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018287 {
18288 rate_flags = pAdapter->maxRateFlags;
18289 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018290
Jeff Johnson295189b2012-06-20 16:38:30 -070018291 //convert to the UI units of 100kbps
18292 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18293
18294#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018295 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 -070018296 sinfo->signal,
18297 pCfg->reportMaxLinkSpeed,
18298 myRate,
18299 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018300 (int) pCfg->linkSpeedRssiMid,
18301 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018302 (int) rate_flags,
18303 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018304#endif //LINKSPEED_DEBUG_ENABLED
18305
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18307 /* assume basic BW. anything else will override this later */
18308 sinfo->txrate.bw = RATE_INFO_BW_20;
18309#endif
18310
Jeff Johnson295189b2012-06-20 16:38:30 -070018311 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18312 {
18313 // we do not want to necessarily report the current speed
18314 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18315 {
18316 // report the max possible speed
18317 rssidx = 0;
18318 }
18319 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18320 {
18321 // report the max possible speed with RSSI scaling
18322 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18323 {
18324 // report the max possible speed
18325 rssidx = 0;
18326 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018327 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018328 {
18329 // report middle speed
18330 rssidx = 1;
18331 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018332 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18333 {
18334 // report middle speed
18335 rssidx = 2;
18336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018337 else
18338 {
18339 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018340 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018341 }
18342 }
18343 else
18344 {
18345 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18346 hddLog(VOS_TRACE_LEVEL_ERROR,
18347 "%s: Invalid value for reportMaxLinkSpeed: %u",
18348 __func__, pCfg->reportMaxLinkSpeed);
18349 rssidx = 0;
18350 }
18351
18352 maxRate = 0;
18353
18354 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018355 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18356 OperationalRates, &ORLeng))
18357 {
18358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18359 /*To keep GUI happy*/
18360 return 0;
18361 }
18362
Jeff Johnson295189b2012-06-20 16:38:30 -070018363 for (i = 0; i < ORLeng; i++)
18364 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018365 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018366 {
18367 /* Validate Rate Set */
18368 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18369 {
18370 currentRate = supported_data_rate[j].supported_rate[rssidx];
18371 break;
18372 }
18373 }
18374 /* Update MAX rate */
18375 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18376 }
18377
18378 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018379 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18380 ExtendedRates, &ERLeng))
18381 {
18382 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18383 /*To keep GUI happy*/
18384 return 0;
18385 }
18386
Jeff Johnson295189b2012-06-20 16:38:30 -070018387 for (i = 0; i < ERLeng; i++)
18388 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018389 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018390 {
18391 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18392 {
18393 currentRate = supported_data_rate[j].supported_rate[rssidx];
18394 break;
18395 }
18396 }
18397 /* Update MAX rate */
18398 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18399 }
c_hpothu79aab322014-07-14 21:11:01 +053018400
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018401 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018402 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018403 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018404 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018405 {
c_hpothu79aab322014-07-14 21:11:01 +053018406 if (rate_flags & eHAL_TX_RATE_VHT80)
18407 mode = 2;
18408 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18409 mode = 1;
18410 else
18411 mode = 0;
18412
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018413 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18414 MCSRates, &MCSLeng))
18415 {
18416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18417 /*To keep GUI happy*/
18418 return 0;
18419 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018420 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018421#ifdef WLAN_FEATURE_11AC
18422 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018423 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018424 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018425 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018426 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018427 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018428 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018429 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018430 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018431 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018432 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018433 maxMCSIdx = 7;
18434 }
18435 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18436 {
18437 maxMCSIdx = 8;
18438 }
18439 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18440 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018441 //VHT20 is supporting 0~8
18442 if (rate_flags & eHAL_TX_RATE_VHT20)
18443 maxMCSIdx = 8;
18444 else
18445 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018446 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018447
c_hpothu79aab322014-07-14 21:11:01 +053018448 if (0 != rssidx)/*check for scaled */
18449 {
18450 //get middle rate MCS index if rssi=1/2
18451 for (i=0; i <= maxMCSIdx; i++)
18452 {
18453 if (sinfo->signal <= rssiMcsTbl[mode][i])
18454 {
18455 maxMCSIdx = i;
18456 break;
18457 }
18458 }
18459 }
18460
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018461 if (rate_flags & eHAL_TX_RATE_VHT80)
18462 {
18463 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18464 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18465 }
18466 else if (rate_flags & eHAL_TX_RATE_VHT40)
18467 {
18468 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18469 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18470 }
18471 else if (rate_flags & eHAL_TX_RATE_VHT20)
18472 {
18473 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18474 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18475 }
18476
Leo Chang6f8870f2013-03-26 18:11:36 -070018477 maxSpeedMCS = 1;
18478 if (currentRate > maxRate)
18479 {
18480 maxRate = currentRate;
18481 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018482
Leo Chang6f8870f2013-03-26 18:11:36 -070018483 }
18484 else
18485#endif /* WLAN_FEATURE_11AC */
18486 {
18487 if (rate_flags & eHAL_TX_RATE_HT40)
18488 {
18489 rateFlag |= 1;
18490 }
18491 if (rate_flags & eHAL_TX_RATE_SGI)
18492 {
18493 rateFlag |= 2;
18494 }
18495
Girish Gowli01abcee2014-07-31 20:18:55 +053018496 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018497 if (rssidx == 1 || rssidx == 2)
18498 {
18499 //get middle rate MCS index if rssi=1/2
18500 for (i=0; i <= 7; i++)
18501 {
18502 if (sinfo->signal <= rssiMcsTbl[mode][i])
18503 {
18504 temp = i+1;
18505 break;
18506 }
18507 }
18508 }
c_hpothu79aab322014-07-14 21:11:01 +053018509
18510 for (i = 0; i < MCSLeng; i++)
18511 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018512 for (j = 0; j < temp; j++)
18513 {
18514 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18515 {
18516 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018517 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018518 break;
18519 }
18520 }
18521 if ((j < temp) && (currentRate > maxRate))
18522 {
18523 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018524 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018525 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018526 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018527 }
18528 }
18529
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018530 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18531 {
18532 maxRate = myRate;
18533 maxSpeedMCS = 1;
18534 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18535 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018536 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018537 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018538 {
18539 maxRate = myRate;
18540 if (rate_flags & eHAL_TX_RATE_LEGACY)
18541 {
18542 maxSpeedMCS = 0;
18543 }
18544 else
18545 {
18546 maxSpeedMCS = 1;
18547 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18548 }
18549 }
18550
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018551 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018552 {
18553 sinfo->txrate.legacy = maxRate;
18554#ifdef LINKSPEED_DEBUG_ENABLED
18555 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18556#endif //LINKSPEED_DEBUG_ENABLED
18557 }
18558 else
18559 {
18560 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018561#ifdef WLAN_FEATURE_11AC
18562 sinfo->txrate.nss = 1;
18563 if (rate_flags & eHAL_TX_RATE_VHT80)
18564 {
18565 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018566#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18567 defined(WITH_BACKPORTS)
18568 sinfo->txrate.bw = RATE_INFO_BW_80;
18569#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018570 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018571#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018572 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018573 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018574 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018575 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018576#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18577 defined(WITH_BACKPORTS)
18578 sinfo->txrate.bw = RATE_INFO_BW_40;
18579#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018580 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018581#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018582 }
18583 else if (rate_flags & eHAL_TX_RATE_VHT20)
18584 {
18585 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18586 }
18587#endif /* WLAN_FEATURE_11AC */
18588 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18589 {
18590 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18591 if (rate_flags & eHAL_TX_RATE_HT40)
18592 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18594 defined(WITH_BACKPORTS)
18595 sinfo->txrate.bw = RATE_INFO_BW_40;
18596#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018597 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018598#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018599 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018600 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018601 if (rate_flags & eHAL_TX_RATE_SGI)
18602 {
18603 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18604 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018605
Jeff Johnson295189b2012-06-20 16:38:30 -070018606#ifdef LINKSPEED_DEBUG_ENABLED
18607 pr_info("Reporting MCS rate %d flags %x\n",
18608 sinfo->txrate.mcs,
18609 sinfo->txrate.flags );
18610#endif //LINKSPEED_DEBUG_ENABLED
18611 }
18612 }
18613 else
18614 {
18615 // report current rate instead of max rate
18616
18617 if (rate_flags & eHAL_TX_RATE_LEGACY)
18618 {
18619 //provide to the UI in units of 100kbps
18620 sinfo->txrate.legacy = myRate;
18621#ifdef LINKSPEED_DEBUG_ENABLED
18622 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18623#endif //LINKSPEED_DEBUG_ENABLED
18624 }
18625 else
18626 {
18627 //must be MCS
18628 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018629#ifdef WLAN_FEATURE_11AC
18630 sinfo->txrate.nss = 1;
18631 if (rate_flags & eHAL_TX_RATE_VHT80)
18632 {
18633 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18634 }
18635 else
18636#endif /* WLAN_FEATURE_11AC */
18637 {
18638 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18639 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018640 if (rate_flags & eHAL_TX_RATE_SGI)
18641 {
18642 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18643 }
18644 if (rate_flags & eHAL_TX_RATE_HT40)
18645 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18647 defined(WITH_BACKPORTS)
18648 sinfo->txrate.bw = RATE_INFO_BW_40;
18649#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018650 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018651#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018652 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018653#ifdef WLAN_FEATURE_11AC
18654 else if (rate_flags & eHAL_TX_RATE_VHT80)
18655 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18657 defined(WITH_BACKPORTS)
18658 sinfo->txrate.bw = RATE_INFO_BW_80;
18659#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018660 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018661#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018662 }
18663#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018664#ifdef LINKSPEED_DEBUG_ENABLED
18665 pr_info("Reporting actual MCS rate %d flags %x\n",
18666 sinfo->txrate.mcs,
18667 sinfo->txrate.flags );
18668#endif //LINKSPEED_DEBUG_ENABLED
18669 }
18670 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018671
18672#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18673 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018674 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018675#else
18676 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018678
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018679 sinfo->tx_packets =
18680 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18681 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18682 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18683 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18684
18685 sinfo->tx_retries =
18686 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18687 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18688 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18689 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18690
18691 sinfo->tx_failed =
18692 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18693 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18694 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18695 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18696
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018697#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18698 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018699 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018700 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018701 STATION_INFO_TX_PACKETS |
18702 STATION_INFO_TX_RETRIES |
18703 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018704#else
18705 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18706 BIT(NL80211_STA_INFO_TX_PACKETS) |
18707 BIT(NL80211_STA_INFO_TX_RETRIES) |
18708 BIT(NL80211_STA_INFO_TX_FAILED);
18709#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018710
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018711 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018712
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018713 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18714 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018715 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18716 &sinfo->txrate, sizeof(sinfo->txrate));
18717
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018718 if (rate_flags & eHAL_TX_RATE_LEGACY)
18719 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18720 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18721 sinfo->rx_packets);
18722 else
18723 hddLog(LOG1,
18724 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18725 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18726 sinfo->tx_packets, sinfo->rx_packets);
18727
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018728 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18729 TRACE_CODE_HDD_CFG80211_GET_STA,
18730 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018731 EXIT();
18732 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018733}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18735static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18736 const u8* mac, struct station_info *sinfo)
18737#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018738static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18739 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018740#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018741{
18742 int ret;
18743
18744 vos_ssr_protect(__func__);
18745 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18746 vos_ssr_unprotect(__func__);
18747
18748 return ret;
18749}
18750
18751static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018752 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018753{
18754 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018755 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018756 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018757 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018758
Jeff Johnsone7245742012-09-05 17:12:55 -070018759 ENTER();
18760
Jeff Johnson295189b2012-06-20 16:38:30 -070018761 if (NULL == pAdapter)
18762 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018763 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018764 return -ENODEV;
18765 }
18766
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018767 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18768 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18769 pAdapter->sessionId, timeout));
18770
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018771 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018772 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018773 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018774 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018775 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018776 }
18777
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018778 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18779 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18780 (pHddCtx->cfg_ini->fhostArpOffload) &&
18781 (eConnectionState_Associated ==
18782 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18783 {
Amar Singhald53568e2013-09-26 11:03:45 -070018784
18785 hddLog(VOS_TRACE_LEVEL_INFO,
18786 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018787 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018788 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18789 {
18790 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018791 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018792 __func__, vos_status);
18793 }
18794 }
18795
Jeff Johnson295189b2012-06-20 16:38:30 -070018796 /**The get power cmd from the supplicant gets updated by the nl only
18797 *on successful execution of the function call
18798 *we are oppositely mapped w.r.t mode in the driver
18799 **/
18800 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18801
18802 if (VOS_STATUS_E_FAILURE == vos_status)
18803 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18805 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018806 return -EINVAL;
18807 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018808 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018809 return 0;
18810}
18811
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018812static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18813 struct net_device *dev, bool mode, int timeout)
18814{
18815 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018816
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018817 vos_ssr_protect(__func__);
18818 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18819 vos_ssr_unprotect(__func__);
18820
18821 return ret;
18822}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018823
Jeff Johnson295189b2012-06-20 16:38:30 -070018824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018825static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18826 struct net_device *netdev,
18827 u8 key_index)
18828{
18829 ENTER();
18830 return 0;
18831}
18832
Jeff Johnson295189b2012-06-20 16:38:30 -070018833static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018834 struct net_device *netdev,
18835 u8 key_index)
18836{
18837 int ret;
18838 vos_ssr_protect(__func__);
18839 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18840 vos_ssr_unprotect(__func__);
18841 return ret;
18842}
18843#endif //LINUX_VERSION_CODE
18844
18845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18846static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18847 struct net_device *dev,
18848 struct ieee80211_txq_params *params)
18849{
18850 ENTER();
18851 return 0;
18852}
18853#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18854static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18855 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018856{
Jeff Johnsone7245742012-09-05 17:12:55 -070018857 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018858 return 0;
18859}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018860#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018861
18862#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18863static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018864 struct net_device *dev,
18865 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018866{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018867 int ret;
18868
18869 vos_ssr_protect(__func__);
18870 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18871 vos_ssr_unprotect(__func__);
18872 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018873}
18874#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18875static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18876 struct ieee80211_txq_params *params)
18877{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018878 int ret;
18879
18880 vos_ssr_protect(__func__);
18881 ret = __wlan_hdd_set_txq_params(wiphy, params);
18882 vos_ssr_unprotect(__func__);
18883 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018884}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018885#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018886
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018887static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018888 struct net_device *dev,
18889 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018890{
18891 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018892 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018893 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018894 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018895 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018896 v_CONTEXT_t pVosContext = NULL;
18897 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018898
Jeff Johnsone7245742012-09-05 17:12:55 -070018899 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018900
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018901 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018902 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018904 return -EINVAL;
18905 }
18906
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18908 TRACE_CODE_HDD_CFG80211_DEL_STA,
18909 pAdapter->sessionId, pAdapter->device_mode));
18910
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018911 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18912 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018913 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018914 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018915 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018916 }
18917
Jeff Johnson295189b2012-06-20 16:38:30 -070018918 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018919 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018920 )
18921 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018922 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18923 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18924 if(pSapCtx == NULL){
18925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18926 FL("psapCtx is NULL"));
18927 return -ENOENT;
18928 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018929 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18930 {
18931 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18932 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18933 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18934 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018935 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018936 {
18937 v_U16_t i;
18938 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18939 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018940 if ((pSapCtx->aStaInfo[i].isUsed) &&
18941 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018942 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018943 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018944 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018945 ETHER_ADDR_LEN);
18946
Jeff Johnson295189b2012-06-20 16:38:30 -070018947 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018948 "%s: Delete STA with MAC::"
18949 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018950 __func__,
18951 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18952 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018953 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018954 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018955 }
18956 }
18957 }
18958 else
18959 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018960
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018961 vos_status = hdd_softap_GetStaId(pAdapter,
18962 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018963 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18964 {
18965 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018966 "%s: Skip this DEL STA as this is not used::"
18967 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018968 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018969 return -ENOENT;
18970 }
18971
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018972 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018973 {
18974 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018975 "%s: Skip this DEL STA as deauth is in progress::"
18976 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018977 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018978 return -ENOENT;
18979 }
18980
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018981 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018982
Jeff Johnson295189b2012-06-20 16:38:30 -070018983 hddLog(VOS_TRACE_LEVEL_INFO,
18984 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018985 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018986 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018987 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018988
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018989 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018990 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18991 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018992 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018993 hddLog(VOS_TRACE_LEVEL_INFO,
18994 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018995 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018996 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018997 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018998 return -ENOENT;
18999 }
19000
Jeff Johnson295189b2012-06-20 16:38:30 -070019001 }
19002 }
19003
19004 EXIT();
19005
19006 return 0;
19007}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019008
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019009#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053019010int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019011 struct net_device *dev,
19012 struct station_del_parameters *param)
19013#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053019015int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019016 struct net_device *dev, const u8 *mac)
19017#else
Kapil Gupta137ef892016-12-13 19:38:00 +053019018int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019019 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019020#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019021#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019022{
19023 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019024 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070019025
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019026 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019027
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019028#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019029 if (NULL == param) {
19030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019031 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019032 return -EINVAL;
19033 }
19034
19035 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19036 param->subtype, &delStaParams);
19037
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019038#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019039 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019040 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019041#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019042 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19043
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019044 vos_ssr_unprotect(__func__);
19045
19046 return ret;
19047}
19048
19049static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019050 struct net_device *dev,
19051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19052 const u8 *mac,
19053#else
19054 u8 *mac,
19055#endif
19056 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019057{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019058 hdd_adapter_t *pAdapter;
19059 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019060 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019061#ifdef FEATURE_WLAN_TDLS
19062 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019063
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019064 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019065
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019066 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19067 if (NULL == pAdapter)
19068 {
19069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19070 "%s: Adapter is NULL",__func__);
19071 return -EINVAL;
19072 }
19073 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19074 status = wlan_hdd_validate_context(pHddCtx);
19075 if (0 != status)
19076 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019077 return status;
19078 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19081 TRACE_CODE_HDD_CFG80211_ADD_STA,
19082 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019083 mask = params->sta_flags_mask;
19084
19085 set = params->sta_flags_set;
19086
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019088 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19089 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019090
19091 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19092 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019093 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019094 }
19095 }
19096#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019097 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019098 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019099}
19100
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19102static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19103 struct net_device *dev, const u8 *mac,
19104 struct station_parameters *params)
19105#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019106static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19107 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019108#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019109{
19110 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019111
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019112 vos_ssr_protect(__func__);
19113 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19114 vos_ssr_unprotect(__func__);
19115
19116 return ret;
19117}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019118#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019119
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019120static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019121 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019122{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19124 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019125 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019126 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019127 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019128 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019129
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019130 ENTER();
19131
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019132 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019133 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019134 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019136 return -EINVAL;
19137 }
19138
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019139 if (!pmksa) {
19140 hddLog(LOGE, FL("pmksa is NULL"));
19141 return -EINVAL;
19142 }
19143
19144 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019145 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019146 pmksa->bssid, pmksa->pmkid);
19147 return -EINVAL;
19148 }
19149
19150 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19151 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19152
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019153 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19154 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019155 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019156 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019157 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019158 }
19159
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019160 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019161 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19162
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019163 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19164 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019165
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019166 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019167 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019168 &pmk_id, 1, FALSE);
19169
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019170 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19171 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19172 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019173
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019174 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019175 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019176}
19177
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019178static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19179 struct cfg80211_pmksa *pmksa)
19180{
19181 int ret;
19182
19183 vos_ssr_protect(__func__);
19184 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19185 vos_ssr_unprotect(__func__);
19186
19187 return ret;
19188}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019189
Wilson Yang6507c4e2013-10-01 20:11:19 -070019190
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019191static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019192 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019193{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019194 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19195 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019196 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019197 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019198
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019199 ENTER();
19200
Wilson Yang6507c4e2013-10-01 20:11:19 -070019201 /* Validate pAdapter */
19202 if (NULL == pAdapter)
19203 {
19204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19205 return -EINVAL;
19206 }
19207
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019208 if (!pmksa) {
19209 hddLog(LOGE, FL("pmksa is NULL"));
19210 return -EINVAL;
19211 }
19212
19213 if (!pmksa->bssid) {
19214 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19215 return -EINVAL;
19216 }
19217
Kiet Lam98c46a12014-10-31 15:34:57 -070019218 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19219 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19220
Wilson Yang6507c4e2013-10-01 20:11:19 -070019221 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19222 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019223 if (0 != status)
19224 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019225 return status;
19226 }
19227
19228 /*Retrieve halHandle*/
19229 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19230
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019231 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19232 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19233 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019234 /* Delete the PMKID CSR cache */
19235 if (eHAL_STATUS_SUCCESS !=
19236 sme_RoamDelPMKIDfromCache(halHandle,
19237 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19238 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19239 MAC_ADDR_ARRAY(pmksa->bssid));
19240 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019241 }
19242
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019243 EXIT();
19244 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019245}
19246
Wilson Yang6507c4e2013-10-01 20:11:19 -070019247
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019248static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19249 struct cfg80211_pmksa *pmksa)
19250{
19251 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019252
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019253 vos_ssr_protect(__func__);
19254 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19255 vos_ssr_unprotect(__func__);
19256
19257 return ret;
19258
19259}
19260
19261static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019262{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019263 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19264 tHalHandle halHandle;
19265 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019266 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019267
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019268 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019269
19270 /* Validate pAdapter */
19271 if (NULL == pAdapter)
19272 {
19273 hddLog(VOS_TRACE_LEVEL_ERROR,
19274 "%s: Invalid Adapter" ,__func__);
19275 return -EINVAL;
19276 }
19277
19278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19279 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019280 if (0 != status)
19281 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019282 return status;
19283 }
19284
19285 /*Retrieve halHandle*/
19286 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19287
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019288 /* Flush the PMKID cache in CSR */
19289 if (eHAL_STATUS_SUCCESS !=
19290 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19292 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019293 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019294 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019295 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019296}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019297
19298static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19299{
19300 int ret;
19301
19302 vos_ssr_protect(__func__);
19303 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19304 vos_ssr_unprotect(__func__);
19305
19306 return ret;
19307}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019308#endif
19309
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019310#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019311static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19312 struct net_device *dev,
19313 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019314{
19315 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19316 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019317 hdd_context_t *pHddCtx;
19318 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019320 ENTER();
19321
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019322 if (NULL == pAdapter)
19323 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019325 return -ENODEV;
19326 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019327 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19328 ret = wlan_hdd_validate_context(pHddCtx);
19329 if (0 != ret)
19330 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019331 return ret;
19332 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019333 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019334 if (NULL == pHddStaCtx)
19335 {
19336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19337 return -EINVAL;
19338 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019339
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019340 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19341 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19342 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019343 // Added for debug on reception of Re-assoc Req.
19344 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19345 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019346 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019347 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019348 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019349 }
19350
19351#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019352 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019353 ftie->ie_len);
19354#endif
19355
19356 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019357 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19358 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019359 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019360
19361 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019362 return 0;
19363}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019364
19365static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19366 struct net_device *dev,
19367 struct cfg80211_update_ft_ies_params *ftie)
19368{
19369 int ret;
19370
19371 vos_ssr_protect(__func__);
19372 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19373 vos_ssr_unprotect(__func__);
19374
19375 return ret;
19376}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019377#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019378
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019379#ifdef FEATURE_WLAN_SCAN_PNO
19380
19381void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19382 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19383{
19384 int ret;
19385 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19386 hdd_context_t *pHddCtx;
19387
Nirav Shah80830bf2013-12-31 16:35:12 +053019388 ENTER();
19389
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019390 if (NULL == pAdapter)
19391 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019393 "%s: HDD adapter is Null", __func__);
19394 return ;
19395 }
19396
19397 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19398 if (NULL == pHddCtx)
19399 {
19400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19401 "%s: HDD context is Null!!!", __func__);
19402 return ;
19403 }
19404
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019405 spin_lock(&pHddCtx->schedScan_lock);
19406 if (TRUE == pHddCtx->isWiphySuspended)
19407 {
19408 pHddCtx->isSchedScanUpdatePending = TRUE;
19409 spin_unlock(&pHddCtx->schedScan_lock);
19410 hddLog(VOS_TRACE_LEVEL_INFO,
19411 "%s: Update cfg80211 scan database after it resume", __func__);
19412 return ;
19413 }
19414 spin_unlock(&pHddCtx->schedScan_lock);
19415
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019416 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19417
19418 if (0 > ret)
19419 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019420 else
19421 {
19422 /* Acquire wakelock to handle the case where APP's tries to suspend
19423 * immediatly after the driver gets connect request(i.e after pno)
19424 * from supplicant, this result in app's is suspending and not able
19425 * to process the connect request to AP */
19426 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19427 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019428 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19430 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019431}
19432
19433/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019434 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019435 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019436 */
19437static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19438{
19439 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19440 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019441 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019442 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19443 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019444
19445 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19446 {
19447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19448 "%s: PNO is allowed only in STA interface", __func__);
19449 return eHAL_STATUS_FAILURE;
19450 }
19451
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019452 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19453
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019454 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019455 * active sessions. PNO is allowed only in case when sap session
19456 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019457 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019458 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19459 {
19460 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019461 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019462
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019463 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19464 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19465 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19466 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019467 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19468 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019469 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019470 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019471 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019472 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019473 }
19474 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19475 pAdapterNode = pNext;
19476 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019477 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019478}
19479
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019480void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19481{
19482 hdd_adapter_t *pAdapter = callbackContext;
19483 hdd_context_t *pHddCtx;
19484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019485 ENTER();
19486
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019487 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19488 {
19489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19490 FL("Invalid adapter or adapter has invalid magic"));
19491 return;
19492 }
19493
19494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19495 if (0 != wlan_hdd_validate_context(pHddCtx))
19496 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019497 return;
19498 }
19499
c_hpothub53c45d2014-08-18 16:53:14 +053019500 if (VOS_STATUS_SUCCESS != status)
19501 {
19502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019503 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019504 pHddCtx->isPnoEnable = FALSE;
19505 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019506
19507 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19508 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019509 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019510}
19511
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019512#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19513 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19514/**
19515 * hdd_config_sched_scan_plan() - configures the sched scan plans
19516 * from the framework.
19517 * @pno_req: pointer to PNO scan request
19518 * @request: pointer to scan request from framework
19519 *
19520 * Return: None
19521 */
19522static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19523 struct cfg80211_sched_scan_request *request,
19524 hdd_context_t *hdd_ctx)
19525{
19526 v_U32_t i = 0;
19527
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019528 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019529 for (i = 0; i < request->n_scan_plans; i++)
19530 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019531 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19532 request->scan_plans[i].iterations;
19533 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19534 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019535 }
19536}
19537#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019538static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019539 struct cfg80211_sched_scan_request *request,
19540 hdd_context_t *hdd_ctx)
19541{
19542 v_U32_t i, temp_int;
19543 /* Driver gets only one time interval which is hardcoded in
19544 * supplicant for 10000ms. Taking power consumption into account 6
19545 * timers will be used, Timervalue is increased exponentially
19546 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19547 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19548 * If it is set to 0 only one timer will be used and PNO scan cycle
19549 * will be repeated after each interval specified by supplicant
19550 * till PNO is disabled.
19551 */
19552 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019553 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019554 HDD_PNO_SCAN_TIMERS_SET_ONE;
19555 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019556 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019557 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19558
19559 temp_int = (request->interval)/1000;
19560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19561 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19562 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019563 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019564 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019565 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019566 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019567 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019568 temp_int *= 2;
19569 }
19570 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019571 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019572}
19573#endif
19574
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019575/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019576 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19577 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019578 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019579static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019580 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19581{
19582 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019583 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019584 hdd_context_t *pHddCtx;
19585 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019586 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019587 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19588 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019589 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19590 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019591 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019592 hdd_config_t *pConfig = NULL;
19593 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019595 ENTER();
19596
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019597 if (NULL == pAdapter)
19598 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019600 "%s: HDD adapter is Null", __func__);
19601 return -ENODEV;
19602 }
19603
19604 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019605 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019606
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019607 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019608 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019609 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019610 }
19611
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019612 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019613 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19614 if (NULL == hHal)
19615 {
19616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19617 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019618 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019619 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19621 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19622 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019623 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019624 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019625 {
19626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19627 "%s: aborting the existing scan is unsuccessfull", __func__);
19628 return -EBUSY;
19629 }
19630
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019631 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019632 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019634 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019635 return -EBUSY;
19636 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019637
c_hpothu37f21312014-04-09 21:49:54 +053019638 if (TRUE == pHddCtx->isPnoEnable)
19639 {
19640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19641 FL("already PNO is enabled"));
19642 return -EBUSY;
19643 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019644
19645 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19646 {
19647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19648 "%s: abort ROC failed ", __func__);
19649 return -EBUSY;
19650 }
19651
c_hpothu37f21312014-04-09 21:49:54 +053019652 pHddCtx->isPnoEnable = TRUE;
19653
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019654 pnoRequest.enable = 1; /*Enable PNO */
19655 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019656
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019657 if (( !pnoRequest.ucNetworksCount ) ||
19658 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019659 {
19660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019661 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019662 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019663 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019664 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019665 goto error;
19666 }
19667
19668 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19669 {
19670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019671 "%s: Incorrect number of channels %d",
19672 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019673 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019674 goto error;
19675 }
19676
19677 /* Framework provides one set of channels(all)
19678 * common for all saved profile */
19679 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19680 channels_allowed, &num_channels_allowed))
19681 {
19682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19683 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019684 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019685 goto error;
19686 }
19687 /* Checking each channel against allowed channel list */
19688 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019689 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019690 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019691 char chList [(request->n_channels*5)+1];
19692 int len;
19693 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019694 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019695 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019696 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019697 if (request->channels[i]->hw_value == channels_allowed[indx])
19698 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019699 if ((!pConfig->enableDFSPnoChnlScan) &&
19700 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19701 {
19702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19703 "%s : Dropping DFS channel : %d",
19704 __func__,channels_allowed[indx]);
19705 num_ignore_dfs_ch++;
19706 break;
19707 }
19708
Nirav Shah80830bf2013-12-31 16:35:12 +053019709 valid_ch[num_ch++] = request->channels[i]->hw_value;
19710 len += snprintf(chList+len, 5, "%d ",
19711 request->channels[i]->hw_value);
19712 break ;
19713 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019714 }
19715 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019716 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019717
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019718 /*If all channels are DFS and dropped, then ignore the PNO request*/
19719 if (num_ignore_dfs_ch == request->n_channels)
19720 {
19721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19722 "%s : All requested channels are DFS channels", __func__);
19723 ret = -EINVAL;
19724 goto error;
19725 }
19726 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019727
19728 pnoRequest.aNetworks =
19729 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19730 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019731 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019732 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19733 FL("failed to allocate memory aNetworks %u"),
19734 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19735 goto error;
19736 }
19737 vos_mem_zero(pnoRequest.aNetworks,
19738 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19739
19740 /* Filling per profile params */
19741 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19742 {
19743 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019744 request->match_sets[i].ssid.ssid_len;
19745
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019746 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19747 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019748 {
19749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019750 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019751 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019752 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019753 goto error;
19754 }
19755
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019756 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019757 request->match_sets[i].ssid.ssid,
19758 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19760 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019761 i, pnoRequest.aNetworks[i].ssId.ssId);
19762 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19763 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19764 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019765
19766 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019767 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19768 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019769
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019770 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019771 }
19772
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019773 for (i = 0; i < request->n_ssids; i++)
19774 {
19775 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019776 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019777 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019778 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019779 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019780 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019781 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019782 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019783 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019784 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019785 break;
19786 }
19787 j++;
19788 }
19789 }
19790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19791 "Number of hidden networks being Configured = %d",
19792 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019794 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019795
19796 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19797 if (pnoRequest.p24GProbeTemplate == NULL)
19798 {
19799 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19800 FL("failed to allocate memory p24GProbeTemplate %u"),
19801 SIR_PNO_MAX_PB_REQ_SIZE);
19802 goto error;
19803 }
19804
19805 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19806 if (pnoRequest.p5GProbeTemplate == NULL)
19807 {
19808 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19809 FL("failed to allocate memory p5GProbeTemplate %u"),
19810 SIR_PNO_MAX_PB_REQ_SIZE);
19811 goto error;
19812 }
19813
19814 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19815 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19816
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019817 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19818 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019819 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019820 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19821 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19822 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019823
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019824 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19825 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19826 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019827 }
19828
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019829 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019830
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019831 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019832
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019833 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019834 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19835 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019836 pAdapter->pno_req_status = 0;
19837
Nirav Shah80830bf2013-12-31 16:35:12 +053019838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19839 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019840 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19841 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019842
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019843 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019844 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019845 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19846 if (eHAL_STATUS_SUCCESS != status)
19847 {
19848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019849 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019850 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019851 goto error;
19852 }
19853
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019854 ret = wait_for_completion_timeout(
19855 &pAdapter->pno_comp_var,
19856 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19857 if (0 >= ret)
19858 {
19859 // Did not receive the response for PNO enable in time.
19860 // Assuming the PNO enable was success.
19861 // Returning error from here, because we timeout, results
19862 // in side effect of Wifi (Wifi Setting) not to work.
19863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19864 FL("Timed out waiting for PNO to be Enabled"));
19865 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019866 }
19867
19868 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019869 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019870
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019871error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19873 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019874 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019875 if (pnoRequest.aNetworks)
19876 vos_mem_free(pnoRequest.aNetworks);
19877 if (pnoRequest.p24GProbeTemplate)
19878 vos_mem_free(pnoRequest.p24GProbeTemplate);
19879 if (pnoRequest.p5GProbeTemplate)
19880 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019881
19882 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019883 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019884}
19885
19886/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019887 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19888 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019889 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019890static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19891 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19892{
19893 int ret;
19894
19895 vos_ssr_protect(__func__);
19896 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19897 vos_ssr_unprotect(__func__);
19898
19899 return ret;
19900}
19901
19902/*
19903 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19904 * Function to disable PNO
19905 */
19906static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019907 struct net_device *dev)
19908{
19909 eHalStatus status = eHAL_STATUS_FAILURE;
19910 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19911 hdd_context_t *pHddCtx;
19912 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019913 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019914 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019915
19916 ENTER();
19917
19918 if (NULL == pAdapter)
19919 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019921 "%s: HDD adapter is Null", __func__);
19922 return -ENODEV;
19923 }
19924
19925 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019926
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019927 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019928 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019930 "%s: HDD context is Null", __func__);
19931 return -ENODEV;
19932 }
19933
19934 /* The return 0 is intentional when isLogpInProgress and
19935 * isLoadUnloadInProgress. We did observe a crash due to a return of
19936 * failure in sched_scan_stop , especially for a case where the unload
19937 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19938 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19939 * success. If it returns a failure , then its next invocation due to the
19940 * clean up of the second interface will have the dev pointer corresponding
19941 * to the first one leading to a crash.
19942 */
19943 if (pHddCtx->isLogpInProgress)
19944 {
19945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19946 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019947 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019948 return ret;
19949 }
19950
Mihir Shete18156292014-03-11 15:38:30 +053019951 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019952 {
19953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19954 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19955 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019956 }
19957
19958 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19959 if (NULL == hHal)
19960 {
19961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19962 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019963 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019964 }
19965
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019966 pnoRequest.enable = 0; /* Disable PNO */
19967 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019968
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19970 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19971 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019972
19973 INIT_COMPLETION(pAdapter->pno_comp_var);
19974 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19975 pnoRequest.callbackContext = pAdapter;
19976 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019977 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019978 pAdapter->sessionId,
19979 NULL, pAdapter);
19980 if (eHAL_STATUS_SUCCESS != status)
19981 {
19982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19983 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019984 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019985 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019986 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019987 ret = wait_for_completion_timeout(
19988 &pAdapter->pno_comp_var,
19989 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19990 if (0 >= ret)
19991 {
19992 // Did not receive the response for PNO disable in time.
19993 // Assuming the PNO disable was success.
19994 // Returning error from here, because we timeout, results
19995 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019997 FL("Timed out waiting for PNO to be disabled"));
19998 ret = 0;
19999 }
20000
20001 ret = pAdapter->pno_req_status;
20002 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020003
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020004error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020006 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020007
20008 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020009 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020010}
20011
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020012/*
20013 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
20014 * NL interface to disable PNO
20015 */
20016static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
20017 struct net_device *dev)
20018{
20019 int ret;
20020
20021 vos_ssr_protect(__func__);
20022 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
20023 vos_ssr_unprotect(__func__);
20024
20025 return ret;
20026}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020027#endif /*FEATURE_WLAN_SCAN_PNO*/
20028
20029
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020030#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020031#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020032static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20033 struct net_device *dev,
20034 u8 *peer, u8 action_code,
20035 u8 dialog_token,
20036 u16 status_code, u32 peer_capability,
20037 const u8 *buf, size_t len)
20038#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20040 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020041static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20042 struct net_device *dev,
20043 const u8 *peer, u8 action_code,
20044 u8 dialog_token, u16 status_code,
20045 u32 peer_capability, bool initiator,
20046 const u8 *buf, size_t len)
20047#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20048static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20049 struct net_device *dev,
20050 const u8 *peer, u8 action_code,
20051 u8 dialog_token, u16 status_code,
20052 u32 peer_capability, const u8 *buf,
20053 size_t len)
20054#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20055static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20056 struct net_device *dev,
20057 u8 *peer, u8 action_code,
20058 u8 dialog_token,
20059 u16 status_code, u32 peer_capability,
20060 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020061#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020062static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20063 struct net_device *dev,
20064 u8 *peer, u8 action_code,
20065 u8 dialog_token,
20066 u16 status_code, const u8 *buf,
20067 size_t len)
20068#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020069#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020070{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020071 hdd_adapter_t *pAdapter;
20072 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020073 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020074 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020075 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020076 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020077 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020078 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020079#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020080 u32 peer_capability = 0;
20081#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020082 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020083 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020084 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020085
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020086 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20087 if (NULL == pAdapter)
20088 {
20089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20090 "%s: Adapter is NULL",__func__);
20091 return -EINVAL;
20092 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020093 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20094 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20095 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020096
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020097 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020098 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020099 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020101 "Invalid arguments");
20102 return -EINVAL;
20103 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020104
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020105 if (pHddCtx->isLogpInProgress)
20106 {
20107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20108 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020109 wlan_hdd_tdls_set_link_status(pAdapter,
20110 peer,
20111 eTDLS_LINK_IDLE,
20112 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020113 return -EBUSY;
20114 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020115
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020116 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20117 {
20118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20119 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20120 return -EAGAIN;
20121 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020122
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020123 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20124 if (!pHddTdlsCtx) {
20125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20126 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020127 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020128 }
20129
Hoonki Lee27511902013-03-14 18:19:06 -070020130 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020131 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020133 "%s: TDLS mode is disabled OR not enabled in FW."
20134 MAC_ADDRESS_STR " action %d declined.",
20135 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020136 return -ENOTSUPP;
20137 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020138
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020139 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20140
20141 if( NULL == pHddStaCtx )
20142 {
20143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20144 "%s: HDD station context NULL ",__func__);
20145 return -EINVAL;
20146 }
20147
20148 /* STA should be connected and authenticated
20149 * before sending any TDLS frames
20150 */
20151 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20152 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20153 {
20154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20155 "STA is not connected or unauthenticated. "
20156 "connState %u, uIsAuthenticated %u",
20157 pHddStaCtx->conn_info.connState,
20158 pHddStaCtx->conn_info.uIsAuthenticated);
20159 return -EAGAIN;
20160 }
20161
Hoonki Lee27511902013-03-14 18:19:06 -070020162 /* other than teardown frame, other mgmt frames are not sent if disabled */
20163 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20164 {
20165 /* if tdls_mode is disabled to respond to peer's request */
20166 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20167 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020169 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020170 " TDLS mode is disabled. action %d declined.",
20171 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020172
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020173 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020174 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020175
20176 if (vos_max_concurrent_connections_reached())
20177 {
20178 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20179 return -EINVAL;
20180 }
Hoonki Lee27511902013-03-14 18:19:06 -070020181 }
20182
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020183 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20184 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020185 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020186 {
20187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020188 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020189 " TDLS setup is ongoing. action %d declined.",
20190 __func__, MAC_ADDR_ARRAY(peer), action_code);
20191 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020192 }
20193 }
20194
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020195 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20196 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020197 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020198 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20199 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020200 {
20201 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20202 we return error code at 'add_station()'. Hence we have this
20203 check again in addtion to add_station().
20204 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020205 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020206 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20208 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020209 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20210 __func__, MAC_ADDR_ARRAY(peer), action_code,
20211 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020212 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020213 }
20214 else
20215 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020216 /* maximum reached. tweak to send error code to peer and return
20217 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020218 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20220 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020221 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20222 __func__, MAC_ADDR_ARRAY(peer), status_code,
20223 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020224 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020225 /* fall through to send setup resp with failure status
20226 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020227 }
20228 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020229 else
20230 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020231 mutex_lock(&pHddCtx->tdls_lock);
20232 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020233 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020234 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020235 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020237 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20238 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020239 return -EPERM;
20240 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020241 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020242 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020243 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020244
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020246 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020247 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20248 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020249
Hoonki Leea34dd892013-02-05 22:56:02 -080020250 /*Except teardown responder will not be used so just make 0*/
20251 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020252 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020253 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020254
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020255 mutex_lock(&pHddCtx->tdls_lock);
20256 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020257
20258 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20259 responder = pTdlsPeer->is_responder;
20260 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020261 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020263 "%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 -070020264 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20265 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020266 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020267 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020268 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020269 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020270 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020271
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020272 /* Discard TDLS setup if peer is removed by user app */
20273 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20274 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20275 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20276 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20277
20278 mutex_lock(&pHddCtx->tdls_lock);
20279 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20280 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20281 mutex_unlock(&pHddCtx->tdls_lock);
20282 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20283 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20284 MAC_ADDR_ARRAY(peer), action_code);
20285 return -EINVAL;
20286 }
20287 mutex_unlock(&pHddCtx->tdls_lock);
20288 }
20289
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020290 /* For explicit trigger of DIS_REQ come out of BMPS for
20291 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020292 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020293 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020294 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20295 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020296 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020297 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020299 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20300 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020301 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20302 if (status != VOS_STATUS_SUCCESS) {
20303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020304 } else {
20305 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020306 }
Hoonki Lee14621352013-04-16 17:51:19 -070020307 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020308 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020309 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20311 }
20312 }
Hoonki Lee14621352013-04-16 17:51:19 -070020313 }
20314
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020315 /* make sure doesn't call send_mgmt() while it is pending */
20316 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20317 {
20318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020319 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020320 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020321 ret = -EBUSY;
20322 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020323 }
20324
20325 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020326 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20327
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020328 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20329 pAdapter->sessionId, peer, action_code, dialog_token,
20330 status_code, peer_capability, (tANI_U8 *)buf, len,
20331 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020332
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020333 if (VOS_STATUS_SUCCESS != status)
20334 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20336 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020337 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020338 ret = -EINVAL;
20339 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020340 }
20341
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20343 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20344 WAIT_TIME_TDLS_MGMT);
20345
Hoonki Leed37cbb32013-04-20 00:31:14 -070020346 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20347 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20348
20349 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020350 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020352 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020353 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020354 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020355
20356 if (pHddCtx->isLogpInProgress)
20357 {
20358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20359 "%s: LOGP in Progress. Ignore!!!", __func__);
20360 return -EAGAIN;
20361 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020362 if (rc <= 0)
20363 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20364 WLAN_LOG_INDICATOR_HOST_DRIVER,
20365 WLAN_LOG_REASON_HDD_TIME_OUT,
20366 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020367
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020368 ret = -EINVAL;
20369 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020370 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020371 else
20372 {
20373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20374 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20375 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20376 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020377
Gopichand Nakkala05922802013-03-14 12:23:19 -070020378 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020379 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020380 ret = max_sta_failed;
20381 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020382 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020383
Hoonki Leea34dd892013-02-05 22:56:02 -080020384 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20385 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020386 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20388 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020389 }
20390 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20391 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020392 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20394 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020395 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020396
20397 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020398
20399tx_failed:
20400 /* add_station will be called before sending TDLS_SETUP_REQ and
20401 * TDLS_SETUP_RSP and as part of add_station driver will enable
20402 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20403 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20404 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20405 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20406 */
20407
20408 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20409 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20410 wlan_hdd_tdls_check_bmps(pAdapter);
20411 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020412}
20413
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020414#if TDLS_MGMT_VERSION2
20415static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20416 u8 *peer, u8 action_code, u8 dialog_token,
20417 u16 status_code, u32 peer_capability,
20418 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020419#else /* TDLS_MGMT_VERSION2 */
20420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20421static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20422 struct net_device *dev,
20423 const u8 *peer, u8 action_code,
20424 u8 dialog_token, u16 status_code,
20425 u32 peer_capability, bool initiator,
20426 const u8 *buf, size_t len)
20427#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20428static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20429 struct net_device *dev,
20430 const u8 *peer, u8 action_code,
20431 u8 dialog_token, u16 status_code,
20432 u32 peer_capability, const u8 *buf,
20433 size_t len)
20434#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20435static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20436 struct net_device *dev,
20437 u8 *peer, u8 action_code,
20438 u8 dialog_token,
20439 u16 status_code, u32 peer_capability,
20440 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020441#else
20442static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20443 u8 *peer, u8 action_code, u8 dialog_token,
20444 u16 status_code, const u8 *buf, size_t len)
20445#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020446#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020447{
20448 int ret;
20449
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020450 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020451#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020452 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20453 dialog_token, status_code,
20454 peer_capability, buf, len);
20455#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20457 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020458 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20459 dialog_token, status_code,
20460 peer_capability, initiator,
20461 buf, len);
20462#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20463 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20464 dialog_token, status_code,
20465 peer_capability, buf, len);
20466#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20467 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20468 dialog_token, status_code,
20469 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020470#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020471 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20472 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020473#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020474#endif
20475 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020476
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020477 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020478}
Atul Mittal115287b2014-07-08 13:26:33 +053020479
20480int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020481#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20482 const u8 *peer,
20483#else
Atul Mittal115287b2014-07-08 13:26:33 +053020484 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020485#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020486 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020487 cfg80211_exttdls_callback callback)
20488{
20489
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020490 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020491 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020492 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20494 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20495 __func__, MAC_ADDR_ARRAY(peer));
20496
20497 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20498 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20499
20500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020501 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20502 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20503 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020504 return -ENOTSUPP;
20505 }
20506
20507 /* To cater the requirement of establishing the TDLS link
20508 * irrespective of the data traffic , get an entry of TDLS peer.
20509 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020510 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020511 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20512 if (pTdlsPeer == NULL) {
20513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20514 "%s: peer " MAC_ADDRESS_STR " not existing",
20515 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020516 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020517 return -EINVAL;
20518 }
20519
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020520 /* check FW TDLS Off Channel capability */
20521 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020522 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020523 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020524 {
20525 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20526 pTdlsPeer->peerParams.global_operating_class =
20527 tdls_peer_params->global_operating_class;
20528 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20529 pTdlsPeer->peerParams.min_bandwidth_kbps =
20530 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020531 /* check configured channel is valid, non dfs and
20532 * not current operating channel */
20533 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20534 tdls_peer_params->channel)) &&
20535 (pHddStaCtx) &&
20536 (tdls_peer_params->channel !=
20537 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020538 {
20539 pTdlsPeer->isOffChannelConfigured = TRUE;
20540 }
20541 else
20542 {
20543 pTdlsPeer->isOffChannelConfigured = FALSE;
20544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20545 "%s: Configured Tdls Off Channel is not valid", __func__);
20546
20547 }
20548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020549 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20550 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020551 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020552 pTdlsPeer->isOffChannelConfigured,
20553 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020554 }
20555 else
20556 {
20557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020558 "%s: TDLS off channel FW capability %d, "
20559 "host capab %d or Invalid TDLS Peer Params", __func__,
20560 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20561 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020562 }
20563
Atul Mittal115287b2014-07-08 13:26:33 +053020564 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20565
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020566 mutex_unlock(&pHddCtx->tdls_lock);
20567
Atul Mittal115287b2014-07-08 13:26:33 +053020568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20569 " %s TDLS Add Force Peer Failed",
20570 __func__);
20571 return -EINVAL;
20572 }
20573 /*EXT TDLS*/
20574
20575 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020576 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20578 " %s TDLS set callback Failed",
20579 __func__);
20580 return -EINVAL;
20581 }
20582
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020583 mutex_unlock(&pHddCtx->tdls_lock);
20584
Atul Mittal115287b2014-07-08 13:26:33 +053020585 return(0);
20586
20587}
20588
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020589int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20590#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20591 const u8 *peer
20592#else
20593 u8 *peer
20594#endif
20595)
Atul Mittal115287b2014-07-08 13:26:33 +053020596{
20597
20598 hddTdlsPeer_t *pTdlsPeer;
20599 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020600
Atul Mittal115287b2014-07-08 13:26:33 +053020601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20602 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20603 __func__, MAC_ADDR_ARRAY(peer));
20604
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020605 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20607 return -EINVAL;
20608 }
20609
Atul Mittal115287b2014-07-08 13:26:33 +053020610 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20611 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20612
20613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020614 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20615 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20616 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020617 return -ENOTSUPP;
20618 }
20619
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020620 mutex_lock(&pHddCtx->tdls_lock);
20621 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020622
20623 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020624 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020626 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020627 __func__, MAC_ADDR_ARRAY(peer));
20628 return -EINVAL;
20629 }
20630 else {
20631 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20632 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020633 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20634 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020635 /* if channel switch is configured, reset
20636 the channel for this peer */
20637 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20638 {
20639 pTdlsPeer->peerParams.channel = 0;
20640 pTdlsPeer->isOffChannelConfigured = FALSE;
20641 }
Atul Mittal115287b2014-07-08 13:26:33 +053020642 }
20643
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020644 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020645 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020647 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020648 }
Atul Mittal115287b2014-07-08 13:26:33 +053020649
20650 /*EXT TDLS*/
20651
20652 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020653 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20655 " %s TDLS set callback Failed",
20656 __func__);
20657 return -EINVAL;
20658 }
Atul Mittal115287b2014-07-08 13:26:33 +053020659
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020660 mutex_unlock(&pHddCtx->tdls_lock);
20661
20662 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020663}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020664static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20666 const u8 *peer,
20667#else
20668 u8 *peer,
20669#endif
20670 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020671{
20672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20673 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020674 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020675 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020677 ENTER();
20678
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020679 if (!pAdapter) {
20680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20681 return -EINVAL;
20682 }
20683
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20685 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20686 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020687 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020688 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020690 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020691 return -EINVAL;
20692 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020693
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020694 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020695 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020696 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020697 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020698 }
20699
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020700
20701 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020702 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020703 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020705 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20706 "Cannot process TDLS commands",
20707 pHddCtx->cfg_ini->fEnableTDLSSupport,
20708 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020709 return -ENOTSUPP;
20710 }
20711
20712 switch (oper) {
20713 case NL80211_TDLS_ENABLE_LINK:
20714 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020715 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020716 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020717 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20718 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020719 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020720 tANI_U16 numCurrTdlsPeers = 0;
20721 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020722 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020723 tSirMacAddr peerMac;
20724 int channel;
20725 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020726
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20728 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20729 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020730
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020731 mutex_lock(&pHddCtx->tdls_lock);
20732 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020733 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020734 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020735 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20737 " (oper %d) not exsting. ignored",
20738 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20739 return -EINVAL;
20740 }
20741
20742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20743 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20744 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20745 "NL80211_TDLS_ENABLE_LINK");
20746
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020747 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20748 {
20749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20750 MAC_ADDRESS_STR " failed",
20751 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020752 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020753 return -EINVAL;
20754 }
20755
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020756 /* before starting tdls connection, set tdls
20757 * off channel established status to default value */
20758 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020759
20760 mutex_unlock(&pHddCtx->tdls_lock);
20761
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020762 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020763 /* TDLS Off Channel, Disable tdls channel switch,
20764 when there are more than one tdls link */
20765 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020766 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020767 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020768 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020769 /* get connected peer and send disable tdls off chan */
20770 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020771 if ((connPeer) &&
20772 (connPeer->isOffChannelSupported == TRUE) &&
20773 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020774 {
20775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20776 "%s: More then one peer connected, Disable "
20777 "TDLS channel switch", __func__);
20778
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020779 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020780 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20781 channel = connPeer->peerParams.channel;
20782
20783 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020784
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020785 ret = sme_SendTdlsChanSwitchReq(
20786 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020787 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020788 peerMac,
20789 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020790 TDLS_OFF_CHANNEL_BW_OFFSET,
20791 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020792 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020793 hddLog(VOS_TRACE_LEVEL_ERROR,
20794 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020795 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020796 }
20797 else
20798 {
20799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20800 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020801 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020802 "isOffChannelConfigured %d",
20803 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020804 (connPeer ? (connPeer->isOffChannelSupported)
20805 : -1),
20806 (connPeer ? (connPeer->isOffChannelConfigured)
20807 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020808 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020809 }
20810 }
20811
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020812 mutex_lock(&pHddCtx->tdls_lock);
20813 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20814 if ( NULL == pTdlsPeer ) {
20815 mutex_unlock(&pHddCtx->tdls_lock);
20816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20817 "%s: " MAC_ADDRESS_STR
20818 " (oper %d) peer got freed in other context. ignored",
20819 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20820 return -EINVAL;
20821 }
20822 peer_status = pTdlsPeer->link_status;
20823 mutex_unlock(&pHddCtx->tdls_lock);
20824
20825 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020826 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020827 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020828
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020829 if (0 != wlan_hdd_tdls_get_link_establish_params(
20830 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020832 return -EINVAL;
20833 }
20834 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020835
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020836 ret = sme_SendTdlsLinkEstablishParams(
20837 WLAN_HDD_GET_HAL_CTX(pAdapter),
20838 pAdapter->sessionId, peer,
20839 &tdlsLinkEstablishParams);
20840 if (ret != VOS_STATUS_SUCCESS) {
20841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20842 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020843 /* Send TDLS peer UAPSD capabilities to the firmware and
20844 * register with the TL on after the response for this operation
20845 * is received .
20846 */
20847 ret = wait_for_completion_interruptible_timeout(
20848 &pAdapter->tdls_link_establish_req_comp,
20849 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020850
20851 mutex_lock(&pHddCtx->tdls_lock);
20852 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20853 if ( NULL == pTdlsPeer ) {
20854 mutex_unlock(&pHddCtx->tdls_lock);
20855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20856 "%s %d: " MAC_ADDRESS_STR
20857 " (oper %d) peer got freed in other context. ignored",
20858 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20859 (int)oper);
20860 return -EINVAL;
20861 }
20862 peer_status = pTdlsPeer->link_status;
20863 mutex_unlock(&pHddCtx->tdls_lock);
20864
20865 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020866 {
20867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020868 FL("Link Establish Request Failed Status %ld"),
20869 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020870 return -EINVAL;
20871 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020872 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020873
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020874 mutex_lock(&pHddCtx->tdls_lock);
20875 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20876 if ( NULL == pTdlsPeer ) {
20877 mutex_unlock(&pHddCtx->tdls_lock);
20878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20879 "%s: " MAC_ADDRESS_STR
20880 " (oper %d) peer got freed in other context. ignored",
20881 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20882 return -EINVAL;
20883 }
20884
Atul Mittal115287b2014-07-08 13:26:33 +053020885 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20886 eTDLS_LINK_CONNECTED,
20887 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020888 staDesc.ucSTAId = pTdlsPeer->staId;
20889 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020890
20891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20892 "%s: tdlsLinkEstablishParams of peer "
20893 MAC_ADDRESS_STR "uapsdQueues: %d"
20894 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20895 "isResponder: %d peerstaId: %d",
20896 __func__,
20897 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20898 tdlsLinkEstablishParams.uapsdQueues,
20899 tdlsLinkEstablishParams.qos,
20900 tdlsLinkEstablishParams.maxSp,
20901 tdlsLinkEstablishParams.isBufSta,
20902 tdlsLinkEstablishParams.isOffChannelSupported,
20903 tdlsLinkEstablishParams.isResponder,
20904 pTdlsPeer->staId);
20905
20906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20907 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20908 __func__,
20909 staDesc.ucSTAId,
20910 staDesc.ucQosEnabled);
20911
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020912 ret = WLANTL_UpdateTdlsSTAClient(
20913 pHddCtx->pvosContext,
20914 &staDesc);
20915 if (ret != VOS_STATUS_SUCCESS) {
20916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20917 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020918
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020919 /* Mark TDLS client Authenticated .*/
20920 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20921 pTdlsPeer->staId,
20922 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020923 if (VOS_STATUS_SUCCESS == status)
20924 {
Hoonki Lee14621352013-04-16 17:51:19 -070020925 if (pTdlsPeer->is_responder == 0)
20926 {
20927 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020928 tdlsConnInfo_t *tdlsInfo;
20929
20930 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20931
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020932 if (!vos_timer_is_initialized(
20933 &pTdlsPeer->initiatorWaitTimeoutTimer))
20934 {
20935 /* Initialize initiator wait callback */
20936 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020937 &pTdlsPeer->initiatorWaitTimeoutTimer,
20938 VOS_TIMER_TYPE_SW,
20939 wlan_hdd_tdls_initiator_wait_cb,
20940 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020941 }
Hoonki Lee14621352013-04-16 17:51:19 -070020942 wlan_hdd_tdls_timer_restart(pAdapter,
20943 &pTdlsPeer->initiatorWaitTimeoutTimer,
20944 WAIT_TIME_TDLS_INITIATOR);
20945 /* suspend initiator TX until it receives direct packet from the
20946 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020947 ret = WLANTL_SuspendDataTx(
20948 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20949 &staId, NULL);
20950 if (ret != VOS_STATUS_SUCCESS) {
20951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20952 }
Hoonki Lee14621352013-04-16 17:51:19 -070020953 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020954
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020955 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020956 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020957 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020958 suppChannelLen =
20959 tdlsLinkEstablishParams.supportedChannelsLen;
20960
20961 if ((suppChannelLen > 0) &&
20962 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20963 {
20964 tANI_U8 suppPeerChannel = 0;
20965 int i = 0;
20966 for (i = 0U; i < suppChannelLen; i++)
20967 {
20968 suppPeerChannel =
20969 tdlsLinkEstablishParams.supportedChannels[i];
20970
20971 pTdlsPeer->isOffChannelSupported = FALSE;
20972 if (suppPeerChannel ==
20973 pTdlsPeer->peerParams.channel)
20974 {
20975 pTdlsPeer->isOffChannelSupported = TRUE;
20976 break;
20977 }
20978 }
20979 }
20980 else
20981 {
20982 pTdlsPeer->isOffChannelSupported = FALSE;
20983 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020984 }
20985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20986 "%s: TDLS channel switch request for channel "
20987 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020988 "%d isOffChannelSupported %d", __func__,
20989 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020990 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020991 suppChannelLen,
20992 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020993
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020994 /* TDLS Off Channel, Enable tdls channel switch,
20995 when their is only one tdls link and it supports */
20996 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20997 if ((numCurrTdlsPeers == 1) &&
20998 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20999 (TRUE == pTdlsPeer->isOffChannelConfigured))
21000 {
21001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21002 "%s: Send TDLS channel switch request for channel %d",
21003 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021004
21005 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021006 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
21007 channel = pTdlsPeer->peerParams.channel;
21008
21009 mutex_unlock(&pHddCtx->tdls_lock);
21010
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021011 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
21012 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021013 peerMac,
21014 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021015 TDLS_OFF_CHANNEL_BW_OFFSET,
21016 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021017 if (ret != VOS_STATUS_SUCCESS) {
21018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
21019 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021020 }
21021 else
21022 {
21023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21024 "%s: TDLS channel switch request not sent"
21025 " numCurrTdlsPeers %d "
21026 "isOffChannelSupported %d "
21027 "isOffChannelConfigured %d",
21028 __func__, numCurrTdlsPeers,
21029 pTdlsPeer->isOffChannelSupported,
21030 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021031 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021032 }
21033
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021034 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021035 else
21036 mutex_unlock(&pHddCtx->tdls_lock);
21037
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021038 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021039
21040 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021041 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21042 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021043 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021044 int ac;
21045 uint8 ucAc[4] = { WLANTL_AC_VO,
21046 WLANTL_AC_VI,
21047 WLANTL_AC_BK,
21048 WLANTL_AC_BE };
21049 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21050 for(ac=0; ac < 4; ac++)
21051 {
21052 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21053 pTdlsPeer->staId, ucAc[ac],
21054 tlTid[ac], tlTid[ac], 0, 0,
21055 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021056 if (status != VOS_STATUS_SUCCESS) {
21057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21058 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021059 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021060 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021061 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021062
Bhargav Shah66896792015-10-01 18:17:37 +053021063 /* stop TCP delack timer if TDLS is enable */
21064 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21065 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021066 hdd_wlan_tdls_enable_link_event(peer,
21067 pTdlsPeer->isOffChannelSupported,
21068 pTdlsPeer->isOffChannelConfigured,
21069 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021070 }
21071 break;
21072 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021073 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021074 tANI_U16 numCurrTdlsPeers = 0;
21075 hddTdlsPeer_t *connPeer = NULL;
21076
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21078 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21079 __func__, MAC_ADDR_ARRAY(peer));
21080
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021081 mutex_lock(&pHddCtx->tdls_lock);
21082 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021083
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021084
Sunil Dutt41de4e22013-11-14 18:09:02 +053021085 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021086 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21088 " (oper %d) not exsting. ignored",
21089 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21090 return -EINVAL;
21091 }
21092
21093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21094 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21095 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21096 "NL80211_TDLS_DISABLE_LINK");
21097
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021098 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021099 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021100 long status;
21101
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021102 /* set tdls off channel status to false for this peer */
21103 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021104 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21105 eTDLS_LINK_TEARING,
21106 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21107 eTDLS_LINK_UNSPECIFIED:
21108 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021109 mutex_unlock(&pHddCtx->tdls_lock);
21110
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021111 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21112
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021113 status = sme_DeleteTdlsPeerSta(
21114 WLAN_HDD_GET_HAL_CTX(pAdapter),
21115 pAdapter->sessionId, peer );
21116 if (status != VOS_STATUS_SUCCESS) {
21117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21118 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021119
21120 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21121 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021122
21123 mutex_lock(&pHddCtx->tdls_lock);
21124 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21125 if ( NULL == pTdlsPeer ) {
21126 mutex_unlock(&pHddCtx->tdls_lock);
21127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21128 " peer was freed in other context",
21129 __func__, MAC_ADDR_ARRAY(peer));
21130 return -EINVAL;
21131 }
21132
Atul Mittal271a7652014-09-12 13:18:22 +053021133 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021134 eTDLS_LINK_IDLE,
21135 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021136 mutex_unlock(&pHddCtx->tdls_lock);
21137
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021138 if (status <= 0)
21139 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21141 "%s: Del station failed status %ld",
21142 __func__, status);
21143 return -EPERM;
21144 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021145
21146 /* TDLS Off Channel, Enable tdls channel switch,
21147 when their is only one tdls link and it supports */
21148 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21149 if (numCurrTdlsPeers == 1)
21150 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021151 tSirMacAddr peerMac;
21152 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021153
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021154 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021155 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021156
21157 if (connPeer == NULL) {
21158 mutex_unlock(&pHddCtx->tdls_lock);
21159 hddLog(VOS_TRACE_LEVEL_ERROR,
21160 "%s connPeer is NULL", __func__);
21161 return -EINVAL;
21162 }
21163
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021164 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21165 channel = connPeer->peerParams.channel;
21166
21167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21168 "%s: TDLS channel switch "
21169 "isOffChannelSupported %d "
21170 "isOffChannelConfigured %d "
21171 "isOffChannelEstablished %d",
21172 __func__,
21173 (connPeer ? connPeer->isOffChannelSupported : -1),
21174 (connPeer ? connPeer->isOffChannelConfigured : -1),
21175 (connPeer ? connPeer->isOffChannelEstablished : -1));
21176
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021177 if ((connPeer) &&
21178 (connPeer->isOffChannelSupported == TRUE) &&
21179 (connPeer->isOffChannelConfigured == TRUE))
21180 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021181 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021182 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021183 status = sme_SendTdlsChanSwitchReq(
21184 WLAN_HDD_GET_HAL_CTX(pAdapter),
21185 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021186 peerMac,
21187 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021188 TDLS_OFF_CHANNEL_BW_OFFSET,
21189 TDLS_CHANNEL_SWITCH_ENABLE);
21190 if (status != VOS_STATUS_SUCCESS) {
21191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21192 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021193 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021194 else
21195 mutex_unlock(&pHddCtx->tdls_lock);
21196 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021197 else
21198 {
21199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21200 "%s: TDLS channel switch request not sent "
21201 "numCurrTdlsPeers %d ",
21202 __func__, numCurrTdlsPeers);
21203 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021204 }
21205 else
21206 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021207 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21209 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021210 }
Bhargav Shah66896792015-10-01 18:17:37 +053021211 if (numCurrTdlsPeers == 0) {
21212 /* start TCP delack timer if TDLS is disable */
21213 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21214 hdd_manage_delack_timer(pHddCtx);
21215 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021216 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021217 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021218 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021219 {
Atul Mittal115287b2014-07-08 13:26:33 +053021220 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021221
Atul Mittal115287b2014-07-08 13:26:33 +053021222 if (0 != status)
21223 {
21224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021225 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021226 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021227 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021228 break;
21229 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021230 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021231 {
Atul Mittal115287b2014-07-08 13:26:33 +053021232 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21233 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021234 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021235 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021236
Atul Mittal115287b2014-07-08 13:26:33 +053021237 if (0 != status)
21238 {
21239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021240 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021241 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021242 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021243 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021244 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021245 case NL80211_TDLS_DISCOVERY_REQ:
21246 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021248 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021249 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021250 return -ENOTSUPP;
21251 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21253 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021254 return -ENOTSUPP;
21255 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021256
21257 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021258 return 0;
21259}
Chilam NG571c65a2013-01-19 12:27:36 +053021260
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021261static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21263 const u8 *peer,
21264#else
21265 u8 *peer,
21266#endif
21267 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021268{
21269 int ret;
21270
21271 vos_ssr_protect(__func__);
21272 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21273 vos_ssr_unprotect(__func__);
21274
21275 return ret;
21276}
21277
Chilam NG571c65a2013-01-19 12:27:36 +053021278int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21279 struct net_device *dev, u8 *peer)
21280{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021281 hddLog(VOS_TRACE_LEVEL_INFO,
21282 "tdls send discover req: "MAC_ADDRESS_STR,
21283 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021284#if TDLS_MGMT_VERSION2
21285 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21286 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21287#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021288#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21289 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21290 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21291#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21292 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21293 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21294#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21295 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21296 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21297#else
Chilam NG571c65a2013-01-19 12:27:36 +053021298 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21299 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021300#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021301#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021302}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021303#endif
21304
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021305#ifdef WLAN_FEATURE_GTK_OFFLOAD
21306/*
21307 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21308 * Callback rountine called upon receiving response for
21309 * get offload info
21310 */
21311void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21312 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21313{
21314
21315 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021316 tANI_U8 tempReplayCounter[8];
21317 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021318
21319 ENTER();
21320
21321 if (NULL == pAdapter)
21322 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021324 "%s: HDD adapter is Null", __func__);
21325 return ;
21326 }
21327
21328 if (NULL == pGtkOffloadGetInfoRsp)
21329 {
21330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21331 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21332 return ;
21333 }
21334
21335 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21336 {
21337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21338 "%s: wlan Failed to get replay counter value",
21339 __func__);
21340 return ;
21341 }
21342
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021343 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21344 /* Update replay counter */
21345 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21346 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21347
21348 {
21349 /* changing from little to big endian since supplicant
21350 * works on big endian format
21351 */
21352 int i;
21353 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21354
21355 for (i = 0; i < 8; i++)
21356 {
21357 tempReplayCounter[7-i] = (tANI_U8)p[i];
21358 }
21359 }
21360
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021361 /* Update replay counter to NL */
21362 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021363 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021364}
21365
21366/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021367 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021368 * This function is used to offload GTK rekeying job to the firmware.
21369 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021370int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021371 struct cfg80211_gtk_rekey_data *data)
21372{
21373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21374 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21375 hdd_station_ctx_t *pHddStaCtx;
21376 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021377 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021378 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021379 eHalStatus status = eHAL_STATUS_FAILURE;
21380
21381 ENTER();
21382
21383 if (NULL == pAdapter)
21384 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021386 "%s: HDD adapter is Null", __func__);
21387 return -ENODEV;
21388 }
21389
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021390 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21391 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21392 pAdapter->sessionId, pAdapter->device_mode));
21393
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021394 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021395 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021396 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021397 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021398 }
21399
21400 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21401 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21402 if (NULL == hHal)
21403 {
21404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21405 "%s: HAL context is Null!!!", __func__);
21406 return -EAGAIN;
21407 }
21408
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021409 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21410 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21411 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21412 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021413 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021414 {
21415 /* changing from big to little endian since driver
21416 * works on little endian format
21417 */
21418 tANI_U8 *p =
21419 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21420 int i;
21421
21422 for (i = 0; i < 8; i++)
21423 {
21424 p[7-i] = data->replay_ctr[i];
21425 }
21426 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021427
21428 if (TRUE == pHddCtx->hdd_wlan_suspended)
21429 {
21430 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021431 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21432 sizeof (tSirGtkOffloadParams));
21433 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021434 pAdapter->sessionId);
21435
21436 if (eHAL_STATUS_SUCCESS != status)
21437 {
21438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21439 "%s: sme_SetGTKOffload failed, returned %d",
21440 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021441
21442 /* Need to clear any trace of key value in the memory.
21443 * Thus zero out the memory even though it is local
21444 * variable.
21445 */
21446 vos_mem_zero(&hddGtkOffloadReqParams,
21447 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021448 return status;
21449 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21451 "%s: sme_SetGTKOffload successfull", __func__);
21452 }
21453 else
21454 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21456 "%s: wlan not suspended GTKOffload request is stored",
21457 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021458 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021459
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021460 /* Need to clear any trace of key value in the memory.
21461 * Thus zero out the memory even though it is local
21462 * variable.
21463 */
21464 vos_mem_zero(&hddGtkOffloadReqParams,
21465 sizeof(hddGtkOffloadReqParams));
21466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021467 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021468 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021469}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021470
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021471int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21472 struct cfg80211_gtk_rekey_data *data)
21473{
21474 int ret;
21475
21476 vos_ssr_protect(__func__);
21477 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21478 vos_ssr_unprotect(__func__);
21479
21480 return ret;
21481}
21482#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021483/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021484 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021485 * This function is used to set access control policy
21486 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021487static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21488 struct net_device *dev,
21489 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021490{
21491 int i;
21492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21493 hdd_hostapd_state_t *pHostapdState;
21494 tsap_Config_t *pConfig;
21495 v_CONTEXT_t pVosContext = NULL;
21496 hdd_context_t *pHddCtx;
21497 int status;
21498
21499 ENTER();
21500
21501 if (NULL == pAdapter)
21502 {
21503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21504 "%s: HDD adapter is Null", __func__);
21505 return -ENODEV;
21506 }
21507
21508 if (NULL == params)
21509 {
21510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21511 "%s: params is Null", __func__);
21512 return -EINVAL;
21513 }
21514
21515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21516 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021517 if (0 != status)
21518 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021519 return status;
21520 }
21521
21522 pVosContext = pHddCtx->pvosContext;
21523 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21524
21525 if (NULL == pHostapdState)
21526 {
21527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21528 "%s: pHostapdState is Null", __func__);
21529 return -EINVAL;
21530 }
21531
21532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21533 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021534 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21535 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21536 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021537
21538 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21539 {
21540 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21541
21542 /* default value */
21543 pConfig->num_accept_mac = 0;
21544 pConfig->num_deny_mac = 0;
21545
21546 /**
21547 * access control policy
21548 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21549 * listed in hostapd.deny file.
21550 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21551 * listed in hostapd.accept file.
21552 */
21553 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21554 {
21555 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21556 }
21557 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21558 {
21559 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21560 }
21561 else
21562 {
21563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21564 "%s:Acl Policy : %d is not supported",
21565 __func__, params->acl_policy);
21566 return -ENOTSUPP;
21567 }
21568
21569 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21570 {
21571 pConfig->num_accept_mac = params->n_acl_entries;
21572 for (i = 0; i < params->n_acl_entries; i++)
21573 {
21574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21575 "** Add ACL MAC entry %i in WhiletList :"
21576 MAC_ADDRESS_STR, i,
21577 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21578
21579 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21580 sizeof(qcmacaddr));
21581 }
21582 }
21583 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21584 {
21585 pConfig->num_deny_mac = params->n_acl_entries;
21586 for (i = 0; i < params->n_acl_entries; i++)
21587 {
21588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21589 "** Add ACL MAC entry %i in BlackList :"
21590 MAC_ADDRESS_STR, i,
21591 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21592
21593 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21594 sizeof(qcmacaddr));
21595 }
21596 }
21597
21598 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21599 {
21600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21601 "%s: SAP Set Mac Acl fail", __func__);
21602 return -EINVAL;
21603 }
21604 }
21605 else
21606 {
21607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021608 "%s: Invalid device_mode = %s (%d)",
21609 __func__, hdd_device_modetoString(pAdapter->device_mode),
21610 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021611 return -EINVAL;
21612 }
21613
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021614 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021615 return 0;
21616}
21617
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021618static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21619 struct net_device *dev,
21620 const struct cfg80211_acl_data *params)
21621{
21622 int ret;
21623 vos_ssr_protect(__func__);
21624 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21625 vos_ssr_unprotect(__func__);
21626
21627 return ret;
21628}
21629
Leo Chang9056f462013-08-01 19:21:11 -070021630#ifdef WLAN_NL80211_TESTMODE
21631#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021632void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021633(
21634 void *pAdapter,
21635 void *indCont
21636)
21637{
Leo Changd9df8aa2013-09-26 13:32:26 -070021638 tSirLPHBInd *lphbInd;
21639 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021640 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021641
21642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021643 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021644
c_hpothu73f35e62014-04-18 13:40:08 +053021645 if (pAdapter == NULL)
21646 {
21647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21648 "%s: pAdapter is NULL\n",__func__);
21649 return;
21650 }
21651
Leo Chang9056f462013-08-01 19:21:11 -070021652 if (NULL == indCont)
21653 {
21654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021655 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021656 return;
21657 }
21658
c_hpothu73f35e62014-04-18 13:40:08 +053021659 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021660 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021661 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021662 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021663 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021664 GFP_ATOMIC);
21665 if (!skb)
21666 {
21667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21668 "LPHB timeout, NL buffer alloc fail");
21669 return;
21670 }
21671
Leo Changac3ba772013-10-07 09:47:04 -070021672 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021673 {
21674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21675 "WLAN_HDD_TM_ATTR_CMD put fail");
21676 goto nla_put_failure;
21677 }
Leo Changac3ba772013-10-07 09:47:04 -070021678 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021679 {
21680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21681 "WLAN_HDD_TM_ATTR_TYPE put fail");
21682 goto nla_put_failure;
21683 }
Leo Changac3ba772013-10-07 09:47:04 -070021684 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021685 sizeof(tSirLPHBInd), lphbInd))
21686 {
21687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21688 "WLAN_HDD_TM_ATTR_DATA put fail");
21689 goto nla_put_failure;
21690 }
Leo Chang9056f462013-08-01 19:21:11 -070021691 cfg80211_testmode_event(skb, GFP_ATOMIC);
21692 return;
21693
21694nla_put_failure:
21695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21696 "NLA Put fail");
21697 kfree_skb(skb);
21698
21699 return;
21700}
21701#endif /* FEATURE_WLAN_LPHB */
21702
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021703static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021704{
21705 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21706 int err = 0;
21707#ifdef FEATURE_WLAN_LPHB
21708 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021709 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021710
21711 ENTER();
21712
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021713 err = wlan_hdd_validate_context(pHddCtx);
21714 if (0 != err)
21715 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021716 return err;
21717 }
Leo Chang9056f462013-08-01 19:21:11 -070021718#endif /* FEATURE_WLAN_LPHB */
21719
21720 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21721 if (err)
21722 {
21723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21724 "%s Testmode INV ATTR", __func__);
21725 return err;
21726 }
21727
21728 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21729 {
21730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21731 "%s Testmode INV CMD", __func__);
21732 return -EINVAL;
21733 }
21734
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021735 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21736 TRACE_CODE_HDD_CFG80211_TESTMODE,
21737 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021738 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21739 {
21740#ifdef FEATURE_WLAN_LPHB
21741 /* Low Power Heartbeat configuration request */
21742 case WLAN_HDD_TM_CMD_WLAN_HB:
21743 {
21744 int buf_len;
21745 void *buf;
21746 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021747 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021748
21749 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21750 {
21751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21752 "%s Testmode INV DATA", __func__);
21753 return -EINVAL;
21754 }
21755
21756 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21757 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021758
Manjeet Singh3c577442017-02-10 19:03:38 +053021759 if (buf_len > sizeof(*hb_params)) {
21760 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21761 buf_len);
21762 return -ERANGE;
21763 }
21764
Amar Singhal05852702014-02-04 14:40:00 -080021765 hb_params_temp =(tSirLPHBReq *)buf;
21766 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21767 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21768 return -EINVAL;
21769
Leo Chang9056f462013-08-01 19:21:11 -070021770 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21771 if (NULL == hb_params)
21772 {
21773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21774 "%s Request Buffer Alloc Fail", __func__);
21775 return -EINVAL;
21776 }
21777
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021778 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021779 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021780 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21781 hb_params,
21782 wlan_hdd_cfg80211_lphb_ind_handler);
21783 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021784 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21786 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021787 vos_mem_free(hb_params);
21788 }
Leo Chang9056f462013-08-01 19:21:11 -070021789 return 0;
21790 }
21791#endif /* FEATURE_WLAN_LPHB */
21792 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21794 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021795 return -EOPNOTSUPP;
21796 }
21797
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021798 EXIT();
21799 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021800}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021801
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021802static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21804 struct wireless_dev *wdev,
21805#endif
21806 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021807{
21808 int ret;
21809
21810 vos_ssr_protect(__func__);
21811 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21812 vos_ssr_unprotect(__func__);
21813
21814 return ret;
21815}
Leo Chang9056f462013-08-01 19:21:11 -070021816#endif /* CONFIG_NL80211_TESTMODE */
21817
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021818extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021819static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021820 struct net_device *dev,
21821 int idx, struct survey_info *survey)
21822{
21823 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21824 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021825 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021826 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021827 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021828 v_S7_t snr,rssi;
21829 int status, i, j, filled = 0;
21830
21831 ENTER();
21832
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021833 if (NULL == pAdapter)
21834 {
21835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21836 "%s: HDD adapter is Null", __func__);
21837 return -ENODEV;
21838 }
21839
21840 if (NULL == wiphy)
21841 {
21842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21843 "%s: wiphy is Null", __func__);
21844 return -ENODEV;
21845 }
21846
21847 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21848 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021849 if (0 != status)
21850 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021851 return status;
21852 }
21853
Mihir Sheted9072e02013-08-21 17:02:29 +053021854 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21855
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021856 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021857 0 != pAdapter->survey_idx ||
21858 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021859 {
21860 /* The survey dump ops when implemented completely is expected to
21861 * return a survey of all channels and the ops is called by the
21862 * kernel with incremental values of the argument 'idx' till it
21863 * returns -ENONET. But we can only support the survey for the
21864 * operating channel for now. survey_idx is used to track
21865 * that the ops is called only once and then return -ENONET for
21866 * the next iteration
21867 */
21868 pAdapter->survey_idx = 0;
21869 return -ENONET;
21870 }
21871
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021872 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21873 {
21874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21875 "%s: Roaming in progress, hence return ", __func__);
21876 return -ENONET;
21877 }
21878
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021879 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21880
21881 wlan_hdd_get_snr(pAdapter, &snr);
21882 wlan_hdd_get_rssi(pAdapter, &rssi);
21883
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021884 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21885 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21886 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021887 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21888 hdd_wlan_get_freq(channel, &freq);
21889
21890
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021891 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021892 {
21893 if (NULL == wiphy->bands[i])
21894 {
21895 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21896 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21897 continue;
21898 }
21899
21900 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21901 {
21902 struct ieee80211_supported_band *band = wiphy->bands[i];
21903
21904 if (band->channels[j].center_freq == (v_U16_t)freq)
21905 {
21906 survey->channel = &band->channels[j];
21907 /* The Rx BDs contain SNR values in dB for the received frames
21908 * while the supplicant expects noise. So we calculate and
21909 * return the value of noise (dBm)
21910 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21911 */
21912 survey->noise = rssi - snr;
21913 survey->filled = SURVEY_INFO_NOISE_DBM;
21914 filled = 1;
21915 }
21916 }
21917 }
21918
21919 if (filled)
21920 pAdapter->survey_idx = 1;
21921 else
21922 {
21923 pAdapter->survey_idx = 0;
21924 return -ENONET;
21925 }
21926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021927 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021928 return 0;
21929}
21930
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021931static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21932 struct net_device *dev,
21933 int idx, struct survey_info *survey)
21934{
21935 int ret;
21936
21937 vos_ssr_protect(__func__);
21938 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21939 vos_ssr_unprotect(__func__);
21940
21941 return ret;
21942}
21943
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021944/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021945 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021946 * this is called when cfg80211 driver resume
21947 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21948 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021949int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021950{
21951 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21952 hdd_adapter_t *pAdapter;
21953 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21954 VOS_STATUS status = VOS_STATUS_SUCCESS;
21955
21956 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021957
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021958 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021959 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021960 return 0;
21961 }
21962
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021963 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21964 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021965
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021966 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021967 {
21968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21969 "%s: Resume SoftAP", __func__);
21970 hdd_set_wlan_suspend_mode(false);
21971 }
21972
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021973 spin_lock(&pHddCtx->schedScan_lock);
21974 pHddCtx->isWiphySuspended = FALSE;
21975 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21976 {
21977 spin_unlock(&pHddCtx->schedScan_lock);
21978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21979 "%s: Return resume is not due to PNO indication", __func__);
21980 return 0;
21981 }
21982 // Reset flag to avoid updatating cfg80211 data old results again
21983 pHddCtx->isSchedScanUpdatePending = FALSE;
21984 spin_unlock(&pHddCtx->schedScan_lock);
21985
21986 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21987
21988 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21989 {
21990 pAdapter = pAdapterNode->pAdapter;
21991 if ( (NULL != pAdapter) &&
21992 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21993 {
21994 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021995 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21997 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021998 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021999 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022000 {
22001 /* Acquire wakelock to handle the case where APP's tries to
22002 * suspend immediately after updating the scan results. Whis
22003 * results in app's is in suspended state and not able to
22004 * process the connect request to AP
22005 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053022006 hdd_prevent_suspend_timeout(2000,
22007 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022008 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022009 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022010
22011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22012 "%s : cfg80211 scan result database updated", __func__);
22013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022014 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022015 return 0;
22016
22017 }
22018 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
22019 pAdapterNode = pNext;
22020 }
22021
22022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22023 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022024 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022025 return 0;
22026}
22027
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022028int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
22029{
22030 int ret;
22031
22032 vos_ssr_protect(__func__);
22033 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
22034 vos_ssr_unprotect(__func__);
22035
22036 return ret;
22037}
22038
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022039/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022040 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022041 * this is called when cfg80211 driver suspends
22042 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022043int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022044 struct cfg80211_wowlan *wow)
22045{
22046 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022047 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022048
22049 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022050
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022051 ret = wlan_hdd_validate_context(pHddCtx);
22052 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022053 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022054 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022055 }
22056
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022057 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22059 "%s: Suspend SoftAP", __func__);
22060 hdd_set_wlan_suspend_mode(true);
22061 }
22062
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022063
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022064 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22065 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22066 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022067 pHddCtx->isWiphySuspended = TRUE;
22068
22069 EXIT();
22070
22071 return 0;
22072}
22073
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022074int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22075 struct cfg80211_wowlan *wow)
22076{
22077 int ret;
22078
22079 vos_ssr_protect(__func__);
22080 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22081 vos_ssr_unprotect(__func__);
22082
22083 return ret;
22084}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022085
22086#ifdef FEATURE_OEM_DATA_SUPPORT
22087static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022088 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022089{
22090 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22091
22092 ENTER();
22093
22094 if (wlan_hdd_validate_context(pHddCtx)) {
22095 return;
22096 }
22097 if (!pMsg)
22098 {
22099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22100 return;
22101 }
22102
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022103 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022104
22105 EXIT();
22106 return;
22107
22108}
22109
22110void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022111 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022112{
22113 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22114
22115 ENTER();
22116
22117 if (wlan_hdd_validate_context(pHddCtx)) {
22118 return;
22119 }
22120
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022121 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022122
22123 switch(evType) {
22124 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022125 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022126 break;
22127 default:
22128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22129 break;
22130 }
22131 EXIT();
22132}
22133#endif
22134
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022135#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22136 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022137/**
22138 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22139 * @wiphy: Pointer to wiphy
22140 * @wdev: Pointer to wireless device structure
22141 *
22142 * This function is used to abort an ongoing scan
22143 *
22144 * Return: None
22145 */
22146static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22147 struct wireless_dev *wdev)
22148{
22149 struct net_device *dev = wdev->netdev;
22150 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22151 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22152 int ret;
22153
22154 ENTER();
22155
22156 if (NULL == adapter) {
22157 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22158 return;
22159 }
22160
22161 ret = wlan_hdd_validate_context(hdd_ctx);
22162 if (0 != ret)
22163 return;
22164
22165 wlan_hdd_scan_abort(adapter);
22166
22167 return;
22168}
22169
22170/**
22171 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22172 * @wiphy: Pointer to wiphy
22173 * @wdev: Pointer to wireless device structure
22174 *
22175 * Return: None
22176 */
22177void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22178 struct wireless_dev *wdev)
22179{
22180 vos_ssr_protect(__func__);
22181 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22182 vos_ssr_unprotect(__func__);
22183
22184 return;
22185}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022186#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022187
Abhishek Singh936c6932017-11-07 17:28:23 +053022188#ifdef CHANNEL_SWITCH_SUPPORTED
22189/**
22190 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22191 * channel in SAP/GO
22192 * @wiphy: wiphy pointer
22193 * @dev: dev pointer.
22194 * @csa_params: Change channel params
22195 *
22196 * This function is called to switch channel in SAP/GO
22197 *
22198 * Return: 0 if success else return non zero
22199 */
22200static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22201 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22202{
22203 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22204 hdd_context_t *hdd_ctx;
22205 uint8_t channel;
22206 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022207 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022208 v_CONTEXT_t vos_ctx;
22209
22210 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22211
22212 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22213 ret = wlan_hdd_validate_context(hdd_ctx);
22214 if (ret)
22215 return ret;
22216
22217 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22218 if (!vos_ctx) {
22219 hddLog(LOGE, FL("Vos ctx is null"));
22220 return -EINVAL;
22221 }
22222
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022223 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022224 return -ENOTSUPP;
22225
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022226 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22227 if (!sap_ctx) {
22228 hddLog(LOGE, FL("sap_ctx is NULL"));
22229 return -EINVAL;
22230 }
22231
22232 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22233 if (ret)
22234 return ret;
22235
22236 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22237
Abhishek Singh936c6932017-11-07 17:28:23 +053022238 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022239 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022240
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022241 if (ret) {
22242 wlansap_reset_chan_change_in_progress(sap_ctx);
22243 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22244 }
22245
Abhishek Singh936c6932017-11-07 17:28:23 +053022246 return ret;
22247}
22248
22249/**
22250 * wlan_hdd_cfg80211_channel_switch()- function to switch
22251 * channel in SAP/GO
22252 * @wiphy: wiphy pointer
22253 * @dev: dev pointer.
22254 * @csa_params: Change channel params
22255 *
22256 * This function is called to switch channel in SAP/GO
22257 *
22258 * Return: 0 if success else return non zero
22259 */
22260static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22261 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22262{
22263 int ret;
22264
22265 vos_ssr_protect(__func__);
22266 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22267 vos_ssr_unprotect(__func__);
22268
22269 return ret;
22270}
22271#endif
22272
Jeff Johnson295189b2012-06-20 16:38:30 -070022273/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022274static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022275{
22276 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22277 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22278 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22279 .change_station = wlan_hdd_change_station,
22280#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22281 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22282 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22283 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022284#else
22285 .start_ap = wlan_hdd_cfg80211_start_ap,
22286 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22287 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022288#endif
22289 .change_bss = wlan_hdd_cfg80211_change_bss,
22290 .add_key = wlan_hdd_cfg80211_add_key,
22291 .get_key = wlan_hdd_cfg80211_get_key,
22292 .del_key = wlan_hdd_cfg80211_del_key,
22293 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022294#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022295 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022296#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022297 .scan = wlan_hdd_cfg80211_scan,
22298 .connect = wlan_hdd_cfg80211_connect,
22299 .disconnect = wlan_hdd_cfg80211_disconnect,
22300 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22301 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22302 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22303 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22304 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022305 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22306 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022307 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022308#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22309 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22310 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22311 .set_txq_params = wlan_hdd_set_txq_params,
22312#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022313 .get_station = wlan_hdd_cfg80211_get_station,
22314 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22315 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022316 .add_station = wlan_hdd_cfg80211_add_station,
22317#ifdef FEATURE_WLAN_LFR
22318 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22319 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22320 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22321#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022322#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22323 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22324#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022325#ifdef FEATURE_WLAN_TDLS
22326 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22327 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22328#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022329#ifdef WLAN_FEATURE_GTK_OFFLOAD
22330 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22331#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022332#ifdef FEATURE_WLAN_SCAN_PNO
22333 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22334 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22335#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022336 .resume = wlan_hdd_cfg80211_resume_wlan,
22337 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022338 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022339#ifdef WLAN_NL80211_TESTMODE
22340 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22341#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022342 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22344 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022345 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022346#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022347#ifdef CHANNEL_SWITCH_SUPPORTED
22348 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22349#endif
22350
Jeff Johnson295189b2012-06-20 16:38:30 -070022351};
22352