blob: 4bed86901bc61b64f7bd5df9cefbe8f44cf5a9d2 [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;
12303 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012304 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 eMib_dot11DesiredBssType connectedBssType;
12306 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012307 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012308
12309 ENTER();
12310
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012311 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012312 {
12313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12314 "%s: Adapter context is null", __func__);
12315 return VOS_STATUS_E_FAILURE;
12316 }
12317
12318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12319 if (!pHddCtx)
12320 {
12321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12322 "%s: HDD context is null", __func__);
12323 return VOS_STATUS_E_FAILURE;
12324 }
12325
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012326 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12327 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12328 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012329 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012330 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012332 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 }
12334
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12336 __func__, hdd_device_modetoString(pAdapter->device_mode),
12337 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012338
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012339 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12340 hddLog(VOS_TRACE_LEVEL_FATAL,
12341 "%s: STA + MON is in progress, cannot change interface",
12342 __func__);
12343 }
12344
Agarwal Ashish51325b52014-06-16 16:50:49 +053012345 if (vos_max_concurrent_connections_reached()) {
12346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12347 return -EINVAL;
12348 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012349 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 wdev = ndev->ieee80211_ptr;
12351
12352#ifdef WLAN_BTAMP_FEATURE
12353 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12354 (NL80211_IFTYPE_ADHOC == type)||
12355 (NL80211_IFTYPE_AP == type)||
12356 (NL80211_IFTYPE_P2P_GO == type))
12357 {
12358 pHddCtx->isAmpAllowed = VOS_FALSE;
12359 // stop AMP traffic
12360 status = WLANBAP_StopAmp();
12361 if(VOS_STATUS_SUCCESS != status )
12362 {
12363 pHddCtx->isAmpAllowed = VOS_TRUE;
12364 hddLog(VOS_TRACE_LEVEL_FATAL,
12365 "%s: Failed to stop AMP", __func__);
12366 return -EINVAL;
12367 }
12368 }
12369#endif //WLAN_BTAMP_FEATURE
12370 /* Reset the current device mode bit mask*/
12371 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12372
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012373 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12374 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12375 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012376 {
12377 /* Notify Mode change in case of concurrency.
12378 * Below function invokes TDLS teardown Functionality Since TDLS is
12379 * not Supported in case of concurrency i.e Once P2P session
12380 * is detected disable offchannel and teardown TDLS links
12381 */
12382 hddLog(LOG1,
12383 FL("Device mode = %d Interface type = %d"),
12384 pAdapter->device_mode, type);
12385 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12386 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012387
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012390 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012391 )
12392 {
12393 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012394 if (!pWextState)
12395 {
12396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12397 "%s: pWextState is null", __func__);
12398 return VOS_STATUS_E_FAILURE;
12399 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 pRoamProfile = &pWextState->roamProfile;
12401 LastBSSType = pRoamProfile->BSSType;
12402
12403 switch (type)
12404 {
12405 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012406 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 hddLog(VOS_TRACE_LEVEL_INFO,
12408 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12409 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012410#ifdef WLAN_FEATURE_11AC
12411 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12412 {
12413 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12414 }
12415#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012416 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012417 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012419 //Check for sub-string p2p to confirm its a p2p interface
12420 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012421 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012422#ifdef FEATURE_WLAN_TDLS
12423 mutex_lock(&pHddCtx->tdls_lock);
12424 wlan_hdd_tdls_exit(pAdapter, TRUE);
12425 mutex_unlock(&pHddCtx->tdls_lock);
12426#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012427 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12428 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12429 }
12430 else
12431 {
12432 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012433 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012434 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012435 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012436
Jeff Johnson295189b2012-06-20 16:38:30 -070012437 case NL80211_IFTYPE_ADHOC:
12438 hddLog(VOS_TRACE_LEVEL_INFO,
12439 "%s: setting interface Type to ADHOC", __func__);
12440 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12441 pRoamProfile->phyMode =
12442 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012443 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012445 hdd_set_ibss_ops( pAdapter );
12446 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012447
12448 status = hdd_sta_id_hash_attach(pAdapter);
12449 if (VOS_STATUS_SUCCESS != status) {
12450 hddLog(VOS_TRACE_LEVEL_ERROR,
12451 FL("Failed to initialize hash for IBSS"));
12452 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012453 break;
12454
12455 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012456 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012457 {
12458 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12459 "%s: setting interface Type to %s", __func__,
12460 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12461
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012462 //Cancel any remain on channel for GO mode
12463 if (NL80211_IFTYPE_P2P_GO == type)
12464 {
12465 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12466 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012467 //Disable IMPS & BMPS for SAP/GO
12468 if(VOS_STATUS_E_FAILURE ==
12469 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12470 {
12471 //Fail to Exit BMPS
12472 VOS_ASSERT(0);
12473 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012474
12475 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12476
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012477#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012478
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012479 /* A Mutex Lock is introduced while changing the mode to
12480 * protect the concurrent access for the Adapters by TDLS
12481 * module.
12482 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012483 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012484#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012485 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012486 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12489 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012490#ifdef FEATURE_WLAN_TDLS
12491 mutex_unlock(&pHddCtx->tdls_lock);
12492#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012493 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12494 (pConfig->apRandomBssidEnabled))
12495 {
12496 /* To meet Android requirements create a randomized
12497 MAC address of the form 02:1A:11:Fx:xx:xx */
12498 get_random_bytes(&ndev->dev_addr[3], 3);
12499 ndev->dev_addr[0] = 0x02;
12500 ndev->dev_addr[1] = 0x1A;
12501 ndev->dev_addr[2] = 0x11;
12502 ndev->dev_addr[3] |= 0xF0;
12503 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12504 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012505 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12506 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012507 }
12508
Jeff Johnson295189b2012-06-20 16:38:30 -070012509 hdd_set_ap_ops( pAdapter->dev );
12510
Kiet Lam10841362013-11-01 11:36:50 +053012511 /* This is for only SAP mode where users can
12512 * control country through ini.
12513 * P2P GO follows station country code
12514 * acquired during the STA scanning. */
12515 if((NL80211_IFTYPE_AP == type) &&
12516 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12517 {
12518 int status = 0;
12519 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12520 "%s: setting country code from INI ", __func__);
12521 init_completion(&pAdapter->change_country_code);
12522 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12523 (void *)(tSmeChangeCountryCallback)
12524 wlan_hdd_change_country_code_cb,
12525 pConfig->apCntryCode, pAdapter,
12526 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012527 eSIR_FALSE,
12528 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012529 if (eHAL_STATUS_SUCCESS == status)
12530 {
12531 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012532 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012533 &pAdapter->change_country_code,
12534 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012535 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012536 {
12537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012538 FL("SME Timed out while setting country code %ld"),
12539 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012540
12541 if (pHddCtx->isLogpInProgress)
12542 {
12543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12544 "%s: LOGP in Progress. Ignore!!!", __func__);
12545 return -EAGAIN;
12546 }
Kiet Lam10841362013-11-01 11:36:50 +053012547 }
12548 }
12549 else
12550 {
12551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012552 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012553 return -EINVAL;
12554 }
12555 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012556 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 if(status != VOS_STATUS_SUCCESS)
12558 {
12559 hddLog(VOS_TRACE_LEVEL_FATAL,
12560 "%s: Error initializing the ap mode", __func__);
12561 return -EINVAL;
12562 }
12563 hdd_set_conparam(1);
12564
Nirav Shah7e3c8132015-06-22 23:51:42 +053012565 status = hdd_sta_id_hash_attach(pAdapter);
12566 if (VOS_STATUS_SUCCESS != status)
12567 {
12568 hddLog(VOS_TRACE_LEVEL_ERROR,
12569 FL("Failed to initialize hash for AP"));
12570 return -EINVAL;
12571 }
12572
Jeff Johnson295189b2012-06-20 16:38:30 -070012573 /*interface type changed update in wiphy structure*/
12574 if(wdev)
12575 {
12576 wdev->iftype = type;
12577 pHddCtx->change_iface = type;
12578 }
12579 else
12580 {
12581 hddLog(VOS_TRACE_LEVEL_ERROR,
12582 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12583 return -EINVAL;
12584 }
12585 goto done;
12586 }
12587
12588 default:
12589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12590 __func__);
12591 return -EOPNOTSUPP;
12592 }
12593 }
12594 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 )
12597 {
12598 switch(type)
12599 {
12600 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012603
12604 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012605#ifdef FEATURE_WLAN_TDLS
12606
12607 /* A Mutex Lock is introduced while changing the mode to
12608 * protect the concurrent access for the Adapters by TDLS
12609 * module.
12610 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012611 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012612#endif
c_hpothu002231a2015-02-05 14:58:51 +053012613 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012614 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012615 //Check for sub-string p2p to confirm its a p2p interface
12616 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012617 {
12618 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12619 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12620 }
12621 else
12622 {
12623 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012625 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012626
12627 /* set con_mode to STA only when no SAP concurrency mode */
12628 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12629 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12632 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012633#ifdef FEATURE_WLAN_TDLS
12634 mutex_unlock(&pHddCtx->tdls_lock);
12635#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012636 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012637 if( VOS_STATUS_SUCCESS != status )
12638 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012639 /* In case of JB, for P2P-GO, only change interface will be called,
12640 * This is the right place to enable back bmps_imps()
12641 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012642 if (pHddCtx->hdd_wlan_suspended)
12643 {
12644 hdd_set_pwrparams(pHddCtx);
12645 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012646 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012647 goto done;
12648 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012649 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12652 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 goto done;
12654 default:
12655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12656 __func__);
12657 return -EOPNOTSUPP;
12658
12659 }
12660
12661 }
12662 else
12663 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012664 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12665 __func__, hdd_device_modetoString(pAdapter->device_mode),
12666 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012667 return -EOPNOTSUPP;
12668 }
12669
12670
12671 if(pRoamProfile)
12672 {
12673 if ( LastBSSType != pRoamProfile->BSSType )
12674 {
12675 /*interface type changed update in wiphy structure*/
12676 wdev->iftype = type;
12677
12678 /*the BSS mode changed, We need to issue disconnect
12679 if connected or in IBSS disconnect state*/
12680 if ( hdd_connGetConnectedBssType(
12681 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12682 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12683 {
12684 /*need to issue a disconnect to CSR.*/
12685 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12686 if( eHAL_STATUS_SUCCESS ==
12687 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12688 pAdapter->sessionId,
12689 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12690 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012691 ret = wait_for_completion_interruptible_timeout(
12692 &pAdapter->disconnect_comp_var,
12693 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12694 if (ret <= 0)
12695 {
12696 hddLog(VOS_TRACE_LEVEL_ERROR,
12697 FL("wait on disconnect_comp_var failed %ld"), ret);
12698 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 }
12700 }
12701 }
12702 }
12703
12704done:
12705 /*set bitmask based on updated value*/
12706 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012707
12708 /* Only STA mode support TM now
12709 * all other mode, TM feature should be disabled */
12710 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12711 (~VOS_STA & pHddCtx->concurrency_mode) )
12712 {
12713 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12714 }
12715
Jeff Johnson295189b2012-06-20 16:38:30 -070012716#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012717 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012718 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 {
12720 //we are ok to do AMP
12721 pHddCtx->isAmpAllowed = VOS_TRUE;
12722 }
12723#endif //WLAN_BTAMP_FEATURE
12724 EXIT();
12725 return 0;
12726}
12727
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012728/*
12729 * FUNCTION: wlan_hdd_cfg80211_change_iface
12730 * wrapper function to protect the actual implementation from SSR.
12731 */
12732int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12733 struct net_device *ndev,
12734 enum nl80211_iftype type,
12735 u32 *flags,
12736 struct vif_params *params
12737 )
12738{
12739 int ret;
12740
12741 vos_ssr_protect(__func__);
12742 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12743 vos_ssr_unprotect(__func__);
12744
12745 return ret;
12746}
12747
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012748#ifdef FEATURE_WLAN_TDLS
12749static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012750 struct net_device *dev,
12751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12752 const u8 *mac,
12753#else
12754 u8 *mac,
12755#endif
12756 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012757{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012758 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012759 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012760 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012761 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012762 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012763 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012764
12765 ENTER();
12766
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012767 if (!dev) {
12768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12769 return -EINVAL;
12770 }
12771
12772 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12773 if (!pAdapter) {
12774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12775 return -EINVAL;
12776 }
12777
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012778 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012779 {
12780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12781 "Invalid arguments");
12782 return -EINVAL;
12783 }
Hoonki Lee27511902013-03-14 18:19:06 -070012784
12785 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12786 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12787 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012789 "%s: TDLS mode is disabled OR not enabled in FW."
12790 MAC_ADDRESS_STR " Request declined.",
12791 __func__, MAC_ADDR_ARRAY(mac));
12792 return -ENOTSUPP;
12793 }
12794
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012795 if (pHddCtx->isLogpInProgress)
12796 {
12797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12798 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012799 wlan_hdd_tdls_set_link_status(pAdapter,
12800 mac,
12801 eTDLS_LINK_IDLE,
12802 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012803 return -EBUSY;
12804 }
12805
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012806 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012807 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012808
12809 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012811 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12812 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012813 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012814 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012815 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012816
12817 /* in add station, we accept existing valid staId if there is */
12818 if ((0 == update) &&
12819 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12820 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012821 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012823 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012824 " link_status %d. staId %d. add station ignored.",
12825 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012826 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012827 return 0;
12828 }
12829 /* in change station, we accept only when staId is valid */
12830 if ((1 == update) &&
12831 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12832 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12833 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012834 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012836 "%s: " MAC_ADDRESS_STR
12837 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012838 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12839 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12840 mutex_unlock(&pHddCtx->tdls_lock);
12841 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012842 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012843 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012844
12845 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012846 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012847 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12849 "%s: " MAC_ADDRESS_STR
12850 " TDLS setup is ongoing. Request declined.",
12851 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012852 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012853 }
12854
12855 /* first to check if we reached to maximum supported TDLS peer.
12856 TODO: for now, return -EPERM looks working fine,
12857 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012858 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12859 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012860 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12862 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012863 " TDLS Max peer already connected. Request declined."
12864 " Num of peers (%d), Max allowed (%d).",
12865 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12866 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012867 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012868 }
12869 else
12870 {
12871 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012872 mutex_lock(&pHddCtx->tdls_lock);
12873 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012874 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012875 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012876 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12878 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12879 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012880 return -EPERM;
12881 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012882 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012883 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012884 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012885 wlan_hdd_tdls_set_link_status(pAdapter,
12886 mac,
12887 eTDLS_LINK_CONNECTING,
12888 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012889
Jeff Johnsond75fe012013-04-06 10:53:06 -070012890 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012891 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012892 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012894 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012895 if(StaParams->htcap_present)
12896 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012898 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012900 "ht_capa->extended_capabilities: %0x",
12901 StaParams->HTCap.extendedHtCapInfo);
12902 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012904 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012906 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012907 if(StaParams->vhtcap_present)
12908 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012910 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12911 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12912 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12913 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012914 {
12915 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012917 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012919 "[%d]: %x ", i, StaParams->supported_rates[i]);
12920 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012921 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012922 else if ((1 == update) && (NULL == StaParams))
12923 {
12924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12925 "%s : update is true, but staParams is NULL. Error!", __func__);
12926 return -EPERM;
12927 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012928
12929 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12930
12931 if (!update)
12932 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012933 /*Before adding sta make sure that device exited from BMPS*/
12934 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12935 {
12936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12937 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12938 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12939 if (status != VOS_STATUS_SUCCESS) {
12940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12941 }
12942 }
12943
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012944 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012945 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012946 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012947 hddLog(VOS_TRACE_LEVEL_ERROR,
12948 FL("Failed to add TDLS peer STA. Enable Bmps"));
12949 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012950 return -EPERM;
12951 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012952 }
12953 else
12954 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012955 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012956 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012957 if (ret != eHAL_STATUS_SUCCESS) {
12958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12959 return -EPERM;
12960 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012961 }
12962
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012963 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012964 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12965
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012966 mutex_lock(&pHddCtx->tdls_lock);
12967 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12968
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012969 if ((pTdlsPeer != NULL) &&
12970 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012971 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012972 hddLog(VOS_TRACE_LEVEL_ERROR,
12973 FL("peer link status %u"), pTdlsPeer->link_status);
12974 mutex_unlock(&pHddCtx->tdls_lock);
12975 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012976 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012977 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012978
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012979 if (ret <= 0)
12980 {
12981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12982 "%s: timeout waiting for tdls add station indication %ld",
12983 __func__, ret);
12984 goto error;
12985 }
12986
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012987 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12988 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012990 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012991 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012992 }
12993
12994 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012995
12996error:
Atul Mittal115287b2014-07-08 13:26:33 +053012997 wlan_hdd_tdls_set_link_status(pAdapter,
12998 mac,
12999 eTDLS_LINK_IDLE,
13000 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013001 return -EPERM;
13002
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013003}
13004#endif
13005
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013006VOS_STATUS wlan_hdd_send_sta_authorized_event(
13007 hdd_adapter_t *adapter,
13008 hdd_context_t *hdd_ctx,
13009 const v_MACADDR_t *mac_addr)
13010{
13011 struct sk_buff *vendor_event;
13012 uint32_t sta_flags = 0;
13013 VOS_STATUS status;
13014
13015 ENTER();
13016
13017 if (!hdd_ctx) {
13018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13019 return -EINVAL;
13020 }
13021
13022 vendor_event =
13023 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013024 hdd_ctx->wiphy,
13025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13026 &adapter->wdev,
13027#endif
13028 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013029 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13030 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13031 GFP_KERNEL);
13032 if (!vendor_event) {
13033 hddLog(VOS_TRACE_LEVEL_ERROR,
13034 FL("cfg80211_vendor_event_alloc failed"));
13035 return -EINVAL;
13036 }
13037
13038 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13039
13040 status = nla_put_u32(vendor_event,
13041 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13042 sta_flags);
13043 if (status) {
13044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13045 kfree_skb(vendor_event);
13046 return VOS_STATUS_E_FAILURE;
13047 }
13048 status = nla_put(vendor_event,
13049 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
13050 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13051 if (status) {
13052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13053 kfree_skb(vendor_event);
13054 return VOS_STATUS_E_FAILURE;
13055 }
13056
13057 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13058
13059 EXIT();
13060 return 0;
13061}
13062
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013063static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13066 const u8 *mac,
13067#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013069#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 struct station_parameters *params)
13071{
13072 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013073 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013074 hdd_context_t *pHddCtx;
13075 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013076 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013077 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013078#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013079 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013080 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013081 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013082 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013083#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013084
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013085 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013086
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013087 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013088 if ((NULL == pAdapter))
13089 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013091 "invalid adapter ");
13092 return -EINVAL;
13093 }
13094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13096 TRACE_CODE_HDD_CHANGE_STATION,
13097 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013098 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013099
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013100 ret = wlan_hdd_validate_context(pHddCtx);
13101 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013102 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013103 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013104 }
13105
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013106 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13107
13108 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013109 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13111 "invalid HDD station context");
13112 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013113 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13115
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013116 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13117 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013119 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013121 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 WLANTL_STA_AUTHENTICATED);
13123
Gopichand Nakkala29149562013-05-10 21:43:41 +053013124 if (status != VOS_STATUS_SUCCESS)
13125 {
13126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13127 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13128 return -EINVAL;
13129 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013130 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13131 &STAMacAddress);
13132 if (status != VOS_STATUS_SUCCESS)
13133 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 }
13135 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013136 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13137 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013138#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013139 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13140 StaParams.capability = params->capability;
13141 StaParams.uapsd_queues = params->uapsd_queues;
13142 StaParams.max_sp = params->max_sp;
13143
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013144 /* Convert (first channel , number of channels) tuple to
13145 * the total list of channels. This goes with the assumption
13146 * that if the first channel is < 14, then the next channels
13147 * are an incremental of 1 else an incremental of 4 till the number
13148 * of channels.
13149 */
13150 if (0 != params->supported_channels_len) {
13151 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013152 for ( i = 0 ; i < params->supported_channels_len
13153 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013154 {
13155 int wifi_chan_index;
13156 StaParams.supported_channels[j] = params->supported_channels[i];
13157 wifi_chan_index =
13158 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13159 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013160 for(k=1; k <= no_of_channels
13161 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013162 {
13163 StaParams.supported_channels[j+1] =
13164 StaParams.supported_channels[j] + wifi_chan_index;
13165 j+=1;
13166 }
13167 }
13168 StaParams.supported_channels_len = j;
13169 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013170 if (params->supported_oper_classes_len >
13171 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13173 "received oper classes:%d, resetting it to max supported %d",
13174 params->supported_oper_classes_len,
13175 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13176 params->supported_oper_classes_len =
13177 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13178 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013179 vos_mem_copy(StaParams.supported_oper_classes,
13180 params->supported_oper_classes,
13181 params->supported_oper_classes_len);
13182 StaParams.supported_oper_classes_len =
13183 params->supported_oper_classes_len;
13184
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013185 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13187 "received extn capabilities:%d, resetting it to max supported",
13188 params->ext_capab_len);
13189 params->ext_capab_len = sizeof(StaParams.extn_capability);
13190 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013191 if (0 != params->ext_capab_len)
13192 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013193 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013194
13195 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013196 {
13197 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013198 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013199 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013200
13201 StaParams.supported_rates_len = params->supported_rates_len;
13202
13203 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13204 * The supported_rates array , for all the structures propogating till Add Sta
13205 * to the firmware has to be modified , if the supplicant (ieee80211) is
13206 * modified to send more rates.
13207 */
13208
13209 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13210 */
13211 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13212 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13213
13214 if (0 != StaParams.supported_rates_len) {
13215 int i = 0;
13216 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13217 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013219 "Supported Rates with Length %d", StaParams.supported_rates_len);
13220 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013222 "[%d]: %0x", i, StaParams.supported_rates[i]);
13223 }
13224
13225 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013226 {
13227 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013228 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013229 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013230
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013231 if (0 != params->ext_capab_len ) {
13232 /*Define A Macro : TODO Sunil*/
13233 if ((1<<4) & StaParams.extn_capability[3]) {
13234 isBufSta = 1;
13235 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013236 /* TDLS Channel Switching Support */
13237 if ((1<<6) & StaParams.extn_capability[3]) {
13238 isOffChannelSupported = 1;
13239 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013240 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013241
13242 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013243 (params->ht_capa || params->vht_capa ||
13244 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013245 /* TDLS Peer is WME/QoS capable */
13246 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013247
13248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13249 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13250 __func__, isQosWmmSta, StaParams.htcap_present);
13251
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013252 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13253 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013254 isOffChannelSupported,
13255 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013256
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013257 if (VOS_STATUS_SUCCESS != status) {
13258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13259 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13260 return -EINVAL;
13261 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013262 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13263
13264 if (VOS_STATUS_SUCCESS != status) {
13265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13266 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13267 return -EINVAL;
13268 }
13269 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013270#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013271 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013272 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013273 return status;
13274}
13275
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13277static int wlan_hdd_change_station(struct wiphy *wiphy,
13278 struct net_device *dev,
13279 const u8 *mac,
13280 struct station_parameters *params)
13281#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013282static int wlan_hdd_change_station(struct wiphy *wiphy,
13283 struct net_device *dev,
13284 u8 *mac,
13285 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013286#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013287{
13288 int ret;
13289
13290 vos_ssr_protect(__func__);
13291 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13292 vos_ssr_unprotect(__func__);
13293
13294 return ret;
13295}
13296
Jeff Johnson295189b2012-06-20 16:38:30 -070013297/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013298 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 * This function is used to initialize the key information
13300 */
13301#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013302static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 struct net_device *ndev,
13304 u8 key_index, bool pairwise,
13305 const u8 *mac_addr,
13306 struct key_params *params
13307 )
13308#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013309static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 struct net_device *ndev,
13311 u8 key_index, const u8 *mac_addr,
13312 struct key_params *params
13313 )
13314#endif
13315{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013317 tCsrRoamSetKey setKey;
13318 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013319 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013320 v_U32_t roamId= 0xFF;
13321 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 hdd_hostapd_state_t *pHostapdState;
13323 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013324 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013325 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013326 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013327 v_MACADDR_t *peerMacAddr;
13328 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013329 uint8_t staid = HDD_MAX_STA_COUNT;
13330 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013331
13332 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013333
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13335 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13336 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13338 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013339 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013340 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013341 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013342 }
13343
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13345 __func__, hdd_device_modetoString(pAdapter->device_mode),
13346 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013347
13348 if (CSR_MAX_NUM_KEY <= key_index)
13349 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013350 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 key_index);
13352
13353 return -EINVAL;
13354 }
13355
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013356 if (CSR_MAX_KEY_LEN < params->key_len)
13357 {
13358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13359 params->key_len);
13360
13361 return -EINVAL;
13362 }
13363
Jingxiang Gec438aea2017-10-26 16:44:00 +080013364 if (CSR_MAX_RSC_LEN < params->seq_len)
13365 {
13366 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13367 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013368
13369 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013370 }
13371
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013372 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013373 "%s: called with key index = %d & key length %d & seq length %d",
13374 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013375
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013376 peerMacAddr = (v_MACADDR_t *)mac_addr;
13377
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 /*extract key idx, key len and key*/
13379 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13380 setKey.keyId = key_index;
13381 setKey.keyLength = params->key_len;
13382 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013383 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013384
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013385 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013386 {
13387 case WLAN_CIPHER_SUITE_WEP40:
13388 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13389 break;
13390
13391 case WLAN_CIPHER_SUITE_WEP104:
13392 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13393 break;
13394
13395 case WLAN_CIPHER_SUITE_TKIP:
13396 {
13397 u8 *pKey = &setKey.Key[0];
13398 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13399
13400 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13401
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013402 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013403
13404 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013405 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 |--------------|----------|----------|
13407 <---16bytes---><--8bytes--><--8bytes-->
13408
13409 */
13410 /*Sme expects the 32 bytes key to be in the below order
13411
13412 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013413 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 |--------------|----------|----------|
13415 <---16bytes---><--8bytes--><--8bytes-->
13416 */
13417 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013418 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013419
13420 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013421 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013422
13423 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013424 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013425
13426
13427 break;
13428 }
13429
13430 case WLAN_CIPHER_SUITE_CCMP:
13431 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13432 break;
13433
13434#ifdef FEATURE_WLAN_WAPI
13435 case WLAN_CIPHER_SUITE_SMS4:
13436 {
13437 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13438 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13439 params->key, params->key_len);
13440 return 0;
13441 }
13442#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013443
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013444#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 case WLAN_CIPHER_SUITE_KRK:
13446 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13447 break;
13448#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013449
13450#ifdef WLAN_FEATURE_11W
13451 case WLAN_CIPHER_SUITE_AES_CMAC:
13452 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013453 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013454#endif
13455
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013457 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013459 status = -EOPNOTSUPP;
13460 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 }
13462
13463 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13464 __func__, setKey.encType);
13465
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013466 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013467#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13468 (!pairwise)
13469#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013470 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013471#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013472 )
13473 {
13474 /* set group key*/
13475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13476 "%s- %d: setting Broadcast key",
13477 __func__, __LINE__);
13478 setKey.keyDirection = eSIR_RX_ONLY;
13479 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13480 }
13481 else
13482 {
13483 /* set pairwise key*/
13484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13485 "%s- %d: setting pairwise key",
13486 __func__, __LINE__);
13487 setKey.keyDirection = eSIR_TX_RX;
13488 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013489 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013490 }
13491 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13492 {
13493 setKey.keyDirection = eSIR_TX_RX;
13494 /*Set the group key*/
13495 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13496 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013497
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013498 if ( 0 != status )
13499 {
13500 hddLog(VOS_TRACE_LEVEL_ERROR,
13501 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013502 status = -EINVAL;
13503 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013504 }
13505 /*Save the keys here and call sme_RoamSetKey for setting
13506 the PTK after peer joins the IBSS network*/
13507 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13508 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013509 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013510 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013511 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13512 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13513 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013514 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013515 if( pHostapdState->bssState == BSS_START )
13516 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013517 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13518 vos_status = wlan_hdd_check_ula_done(pAdapter);
13519
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013520 if (peerMacAddr && (pairwise_set_key == true))
13521 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013522
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013523 if ( vos_status != VOS_STATUS_SUCCESS )
13524 {
13525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13526 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13527 __LINE__, vos_status );
13528
13529 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13530
13531 status = -EINVAL;
13532 goto end;
13533 }
13534
Jeff Johnson295189b2012-06-20 16:38:30 -070013535 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13536
13537 if ( status != eHAL_STATUS_SUCCESS )
13538 {
13539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13540 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13541 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013542 status = -EINVAL;
13543 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 }
13545 }
13546
13547 /* Saving WEP keys */
13548 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13549 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13550 {
13551 //Save the wep key in ap context. Issue setkey after the BSS is started.
13552 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13553 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13554 }
13555 else
13556 {
13557 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013558 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13560 }
13561 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013562 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13563 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013564 {
13565 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13566 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13567
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013568#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13569 if (!pairwise)
13570#else
13571 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13572#endif
13573 {
13574 /* set group key*/
13575 if (pHddStaCtx->roam_info.deferKeyComplete)
13576 {
13577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13578 "%s- %d: Perform Set key Complete",
13579 __func__, __LINE__);
13580 hdd_PerformRoamSetKeyComplete(pAdapter);
13581 }
13582 }
13583
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013584 if (pairwise_set_key == true)
13585 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013586
Jeff Johnson295189b2012-06-20 16:38:30 -070013587 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13588
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013589 pWextState->roamProfile.Keys.defaultIndex = key_index;
13590
13591
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013592 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 params->key, params->key_len);
13594
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013595
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013598 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013599 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013600 __func__, setKey.peerMac[0], setKey.peerMac[1],
13601 setKey.peerMac[2], setKey.peerMac[3],
13602 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 setKey.keyDirection);
13604
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013605 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013606
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013607 if ( vos_status != VOS_STATUS_SUCCESS )
13608 {
13609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13611 __LINE__, vos_status );
13612
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013613 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013614
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013615 status = -EINVAL;
13616 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013617
13618 }
13619
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013620#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013621 /* The supplicant may attempt to set the PTK once pre-authentication
13622 is done. Save the key in the UMAC and include it in the ADD BSS
13623 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013624 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013625 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013626 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013627 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13628 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013629 status = 0;
13630 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013631 }
13632 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13633 {
13634 hddLog(VOS_TRACE_LEVEL_ERROR,
13635 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013636 status = -EINVAL;
13637 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013638 }
13639#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013640
13641 /* issue set key request to SME*/
13642 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13643 pAdapter->sessionId, &setKey, &roamId );
13644
13645 if ( 0 != status )
13646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013647 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13649 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013650 status = -EINVAL;
13651 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013652 }
13653
13654
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013655 /* in case of IBSS as there was no information available about WEP keys during
13656 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013658 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13659 !( ( IW_AUTH_KEY_MGMT_802_1X
13660 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13662 )
13663 &&
13664 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13665 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13666 )
13667 )
13668 {
13669 setKey.keyDirection = eSIR_RX_ONLY;
13670 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13671
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013672 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013673 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013674 __func__, setKey.peerMac[0], setKey.peerMac[1],
13675 setKey.peerMac[2], setKey.peerMac[3],
13676 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 setKey.keyDirection);
13678
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013679 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 pAdapter->sessionId, &setKey, &roamId );
13681
13682 if ( 0 != status )
13683 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013684 hddLog(VOS_TRACE_LEVEL_ERROR,
13685 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 __func__, status);
13687 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013688 status = -EINVAL;
13689 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 }
13691 }
13692 }
13693
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013694 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013695 for (i = 0; i < params->seq_len; i++) {
13696 rsc_counter |= (params->seq[i] << i*8);
13697 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013698 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13699 }
13700
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013701end:
13702 /* Need to clear any trace of key value in the memory.
13703 * Thus zero out the memory even though it is local
13704 * variable.
13705 */
13706 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013707 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013708 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013709}
13710
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13712static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13713 struct net_device *ndev,
13714 u8 key_index, bool pairwise,
13715 const u8 *mac_addr,
13716 struct key_params *params
13717 )
13718#else
13719static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13720 struct net_device *ndev,
13721 u8 key_index, const u8 *mac_addr,
13722 struct key_params *params
13723 )
13724#endif
13725{
13726 int ret;
13727 vos_ssr_protect(__func__);
13728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13729 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13730 mac_addr, params);
13731#else
13732 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13733 params);
13734#endif
13735 vos_ssr_unprotect(__func__);
13736
13737 return ret;
13738}
13739
Jeff Johnson295189b2012-06-20 16:38:30 -070013740/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013741 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 * This function is used to get the key information
13743 */
13744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013745static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013748 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013749 const u8 *mac_addr, void *cookie,
13750 void (*callback)(void *cookie, struct key_params*)
13751 )
13752#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013753static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013754 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013755 struct net_device *ndev,
13756 u8 key_index, const u8 *mac_addr, void *cookie,
13757 void (*callback)(void *cookie, struct key_params*)
13758 )
13759#endif
13760{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013762 hdd_wext_state_t *pWextState = NULL;
13763 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013765 hdd_context_t *pHddCtx;
13766 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013767
13768 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013769
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013770 if (NULL == pAdapter)
13771 {
13772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13773 "%s: HDD adapter is Null", __func__);
13774 return -ENODEV;
13775 }
13776
13777 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13778 ret = wlan_hdd_validate_context(pHddCtx);
13779 if (0 != ret)
13780 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013781 return ret;
13782 }
13783
13784 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13785 pRoamProfile = &(pWextState->roamProfile);
13786
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013787 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13788 __func__, hdd_device_modetoString(pAdapter->device_mode),
13789 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013790
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 memset(&params, 0, sizeof(params));
13792
13793 if (CSR_MAX_NUM_KEY <= key_index)
13794 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013797 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013798
13799 switch(pRoamProfile->EncryptionType.encryptionType[0])
13800 {
13801 case eCSR_ENCRYPT_TYPE_NONE:
13802 params.cipher = IW_AUTH_CIPHER_NONE;
13803 break;
13804
13805 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13806 case eCSR_ENCRYPT_TYPE_WEP40:
13807 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13808 break;
13809
13810 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13811 case eCSR_ENCRYPT_TYPE_WEP104:
13812 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13813 break;
13814
13815 case eCSR_ENCRYPT_TYPE_TKIP:
13816 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13817 break;
13818
13819 case eCSR_ENCRYPT_TYPE_AES:
13820 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13821 break;
13822
13823 default:
13824 params.cipher = IW_AUTH_CIPHER_NONE;
13825 break;
13826 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013827
c_hpothuaaf19692014-05-17 17:01:48 +053013828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13829 TRACE_CODE_HDD_CFG80211_GET_KEY,
13830 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013831
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13833 params.seq_len = 0;
13834 params.seq = NULL;
13835 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13836 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013837 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 return 0;
13839}
13840
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13842static int wlan_hdd_cfg80211_get_key(
13843 struct wiphy *wiphy,
13844 struct net_device *ndev,
13845 u8 key_index, bool pairwise,
13846 const u8 *mac_addr, void *cookie,
13847 void (*callback)(void *cookie, struct key_params*)
13848 )
13849#else
13850static int wlan_hdd_cfg80211_get_key(
13851 struct wiphy *wiphy,
13852 struct net_device *ndev,
13853 u8 key_index, const u8 *mac_addr, void *cookie,
13854 void (*callback)(void *cookie, struct key_params*)
13855 )
13856#endif
13857{
13858 int ret;
13859
13860 vos_ssr_protect(__func__);
13861#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13862 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13863 mac_addr, cookie, callback);
13864#else
13865 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13866 callback);
13867#endif
13868 vos_ssr_unprotect(__func__);
13869
13870 return ret;
13871}
13872
Jeff Johnson295189b2012-06-20 16:38:30 -070013873/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013874 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 * This function is used to delete the key information
13876 */
13877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013878static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013880 u8 key_index,
13881 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 const u8 *mac_addr
13883 )
13884#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013885static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013886 struct net_device *ndev,
13887 u8 key_index,
13888 const u8 *mac_addr
13889 )
13890#endif
13891{
13892 int status = 0;
13893
13894 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013895 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013896 //it is observed that this is invalidating peer
13897 //key index whenever re-key is done. This is affecting data link.
13898 //It should be ok to ignore del_key.
13899#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013900 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13901 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13903 tCsrRoamSetKey setKey;
13904 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013905
Jeff Johnson295189b2012-06-20 16:38:30 -070013906 ENTER();
13907
13908 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13909 __func__,pAdapter->device_mode);
13910
13911 if (CSR_MAX_NUM_KEY <= key_index)
13912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 key_index);
13915
13916 return -EINVAL;
13917 }
13918
13919 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13920 setKey.keyId = key_index;
13921
13922 if (mac_addr)
13923 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13924 else
13925 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13926
13927 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13928
13929 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013931 )
13932 {
13933
13934 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13936 if( pHostapdState->bssState == BSS_START)
13937 {
13938 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 if ( status != eHAL_STATUS_SUCCESS )
13941 {
13942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13943 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13944 __LINE__, status );
13945 }
13946 }
13947 }
13948 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013949 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013950 )
13951 {
13952 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13953
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013954 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13955
13956 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013957 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013958 __func__, setKey.peerMac[0], setKey.peerMac[1],
13959 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013961 if(pAdapter->sessionCtx.station.conn_info.connState ==
13962 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013963 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013964 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013966
Jeff Johnson295189b2012-06-20 16:38:30 -070013967 if ( 0 != status )
13968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 "%s: sme_RoamSetKey failure, returned %d",
13971 __func__, status);
13972 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13973 return -EINVAL;
13974 }
13975 }
13976 }
13977#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013978 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013979 return status;
13980}
13981
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013982#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13983static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13984 struct net_device *ndev,
13985 u8 key_index,
13986 bool pairwise,
13987 const u8 *mac_addr
13988 )
13989#else
13990static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13991 struct net_device *ndev,
13992 u8 key_index,
13993 const u8 *mac_addr
13994 )
13995#endif
13996{
13997 int ret;
13998
13999 vos_ssr_protect(__func__);
14000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14001 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
14002 mac_addr);
14003#else
14004 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14005#endif
14006 vos_ssr_unprotect(__func__);
14007
14008 return ret;
14009}
14010
Jeff Johnson295189b2012-06-20 16:38:30 -070014011/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014012 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 * This function is used to set the default tx key index
14014 */
14015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014016static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 struct net_device *ndev,
14018 u8 key_index,
14019 bool unicast, bool multicast)
14020#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014021static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014022 struct net_device *ndev,
14023 u8 key_index)
14024#endif
14025{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014026 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014027 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014028 hdd_wext_state_t *pWextState;
14029 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014030 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014031
14032 ENTER();
14033
Gopichand Nakkala29149562013-05-10 21:43:41 +053014034 if ((NULL == pAdapter))
14035 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014037 "invalid adapter");
14038 return -EINVAL;
14039 }
14040
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014041 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14042 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14043 pAdapter->sessionId, key_index));
14044
Gopichand Nakkala29149562013-05-10 21:43:41 +053014045 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14046 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14047
14048 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14049 {
14050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14051 "invalid Wext state or HDD context");
14052 return -EINVAL;
14053 }
14054
Arif Hussain6d2a3322013-11-17 19:50:10 -080014055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014056 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014057
Jeff Johnson295189b2012-06-20 16:38:30 -070014058 if (CSR_MAX_NUM_KEY <= key_index)
14059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 key_index);
14062
14063 return -EINVAL;
14064 }
14065
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014066 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14067 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014068 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014069 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014070 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014071 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072
Jeff Johnson295189b2012-06-20 16:38:30 -070014073 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014075 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014077 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014078 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014079#ifdef FEATURE_WLAN_WAPI
14080 (eCSR_ENCRYPT_TYPE_WPI !=
14081 pHddStaCtx->conn_info.ucEncryptionType) &&
14082#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014083 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014084 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014085 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014086 {
14087 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014089
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 tCsrRoamSetKey setKey;
14091 v_U32_t roamId= 0xFF;
14092 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014093
14094 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014095 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014096
Jeff Johnson295189b2012-06-20 16:38:30 -070014097 Keys->defaultIndex = (u8)key_index;
14098 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14099 setKey.keyId = key_index;
14100 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014101
14102 vos_mem_copy(&setKey.Key[0],
14103 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014105
Gopichand Nakkala29149562013-05-10 21:43:41 +053014106 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014107
14108 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 &pHddStaCtx->conn_info.bssId[0],
14110 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014111
Gopichand Nakkala29149562013-05-10 21:43:41 +053014112 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14113 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14114 eCSR_ENCRYPT_TYPE_WEP104)
14115 {
14116 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14117 even though ap is configured for WEP-40 encryption. In this canse the key length
14118 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14119 type(104) and switching encryption type to 40*/
14120 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14121 eCSR_ENCRYPT_TYPE_WEP40;
14122 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14123 eCSR_ENCRYPT_TYPE_WEP40;
14124 }
14125
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014126 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014127 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014128
Jeff Johnson295189b2012-06-20 16:38:30 -070014129 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014130 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014132
Jeff Johnson295189b2012-06-20 16:38:30 -070014133 if ( 0 != status )
14134 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014135 hddLog(VOS_TRACE_LEVEL_ERROR,
14136 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014137 status);
14138 return -EINVAL;
14139 }
14140 }
14141 }
14142
14143 /* In SoftAp mode setting key direction for default mode */
14144 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14145 {
14146 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14147 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14148 (eCSR_ENCRYPT_TYPE_AES !=
14149 pWextState->roamProfile.EncryptionType.encryptionType[0])
14150 )
14151 {
14152 /* Saving key direction for default key index to TX default */
14153 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14154 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14155 }
14156 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014157 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 return status;
14159}
14160
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14162static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14163 struct net_device *ndev,
14164 u8 key_index,
14165 bool unicast, bool multicast)
14166#else
14167static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14168 struct net_device *ndev,
14169 u8 key_index)
14170#endif
14171{
14172 int ret;
14173 vos_ssr_protect(__func__);
14174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14175 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14176 multicast);
14177#else
14178 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14179#endif
14180 vos_ssr_unprotect(__func__);
14181
14182 return ret;
14183}
14184
Jeff Johnson295189b2012-06-20 16:38:30 -070014185/*
14186 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14187 * This function is used to inform the BSS details to nl80211 interface.
14188 */
14189static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14190 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14191{
14192 struct net_device *dev = pAdapter->dev;
14193 struct wireless_dev *wdev = dev->ieee80211_ptr;
14194 struct wiphy *wiphy = wdev->wiphy;
14195 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14196 int chan_no;
14197 int ie_length;
14198 const char *ie;
14199 unsigned int freq;
14200 struct ieee80211_channel *chan;
14201 int rssi = 0;
14202 struct cfg80211_bss *bss = NULL;
14203
Jeff Johnson295189b2012-06-20 16:38:30 -070014204 if( NULL == pBssDesc )
14205 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014206 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014207 return bss;
14208 }
14209
14210 chan_no = pBssDesc->channelId;
14211 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14212 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14213
14214 if( NULL == ie )
14215 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014216 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014217 return bss;
14218 }
14219
14220#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14221 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14222 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014223 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014224 }
14225 else
14226 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014227 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014228 }
14229#else
14230 freq = ieee80211_channel_to_frequency(chan_no);
14231#endif
14232
14233 chan = __ieee80211_get_channel(wiphy, freq);
14234
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014235 if (!chan) {
14236 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14237 return NULL;
14238 }
14239
Abhishek Singhaee43942014-06-16 18:55:47 +053014240 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014241
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014242 return cfg80211_inform_bss(wiphy, chan,
14243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14244 CFG80211_BSS_FTYPE_UNKNOWN,
14245#endif
14246 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014247 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014248 pBssDesc->capabilityInfo,
14249 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014250 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014251}
14252
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014253/*
14254 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14255 * interface that BSS might have been lost.
14256 * @pAdapter: adaptor
14257 * @bssid: bssid which might have been lost
14258 *
14259 * Return: bss which is unlinked from kernel cache
14260 */
14261struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14262 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14263{
14264 struct net_device *dev = pAdapter->dev;
14265 struct wireless_dev *wdev = dev->ieee80211_ptr;
14266 struct wiphy *wiphy = wdev->wiphy;
14267 struct cfg80211_bss *bss = NULL;
14268
Abhishek Singh5a597e62016-12-05 15:16:30 +053014269 bss = hdd_get_bss_entry(wiphy,
14270 NULL, bssid,
14271 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014272 if (bss == NULL) {
14273 hddLog(LOGE, FL("BSS not present"));
14274 } else {
14275 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14276 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14277 cfg80211_unlink_bss(wiphy, bss);
14278 }
14279 return bss;
14280}
Jeff Johnson295189b2012-06-20 16:38:30 -070014281
14282
14283/*
14284 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14285 * This function is used to inform the BSS details to nl80211 interface.
14286 */
14287struct cfg80211_bss*
14288wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14289 tSirBssDescription *bss_desc
14290 )
14291{
14292 /*
14293 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14294 already exists in bss data base of cfg80211 for that particular BSS ID.
14295 Using cfg80211_inform_bss_frame to update the bss entry instead of
14296 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14297 now there is no possibility to get the mgmt(probe response) frame from PE,
14298 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14299 cfg80211_inform_bss_frame.
14300 */
14301 struct net_device *dev = pAdapter->dev;
14302 struct wireless_dev *wdev = dev->ieee80211_ptr;
14303 struct wiphy *wiphy = wdev->wiphy;
14304 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014305#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14306 qcom_ie_age *qie_age = NULL;
14307 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14308#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014309 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014310#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 const char *ie =
14312 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14313 unsigned int freq;
14314 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014315 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014317 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14318 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014319 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014320 hdd_context_t *pHddCtx;
14321 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014322#ifdef WLAN_OPEN_SOURCE
14323 struct timespec ts;
14324#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014325
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014326
Wilson Yangf80a0542013-10-07 13:02:37 -070014327 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14328 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014329 if (0 != status)
14330 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014331 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014332 }
14333
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014334 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014335 if (!mgmt)
14336 {
14337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14338 "%s: memory allocation failed ", __func__);
14339 return NULL;
14340 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014341
Jeff Johnson295189b2012-06-20 16:38:30 -070014342 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014343
14344#ifdef WLAN_OPEN_SOURCE
14345 /* Android does not want the timestamp from the frame.
14346 Instead it wants a monotonic increasing value */
14347 get_monotonic_boottime(&ts);
14348 mgmt->u.probe_resp.timestamp =
14349 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14350#else
14351 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14353 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014354
14355#endif
14356
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14358 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014359
14360#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14361 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14362 /* Assuming this is the last IE, copy at the end */
14363 ie_length -=sizeof(qcom_ie_age);
14364 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14365 qie_age->element_id = QCOM_VENDOR_IE_ID;
14366 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14367 qie_age->oui_1 = QCOM_OUI1;
14368 qie_age->oui_2 = QCOM_OUI2;
14369 qie_age->oui_3 = QCOM_OUI3;
14370 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014371 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14372 * bss related timestamp is in units of ms. Due to this when scan results
14373 * are sent to lowi the scan age is high.To address this, send age in units
14374 * of 1/10 ms.
14375 */
14376 qie_age->age = (vos_timer_get_system_time() -
14377 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014378#endif
14379
Jeff Johnson295189b2012-06-20 16:38:30 -070014380 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014381 if (bss_desc->fProbeRsp)
14382 {
14383 mgmt->frame_control |=
14384 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14385 }
14386 else
14387 {
14388 mgmt->frame_control |=
14389 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14390 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014391
14392#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014393 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014394 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014396 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014398 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014399 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014400
14401 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014402 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 }
14404 else
14405 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014406 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14407 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 kfree(mgmt);
14409 return NULL;
14410 }
14411#else
14412 freq = ieee80211_channel_to_frequency(chan_no);
14413#endif
14414 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014415 /*when the band is changed on the fly using the GUI, three things are done
14416 * 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)
14417 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14418 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14419 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14420 * and discards the channels correponding to previous band and calls back with zero bss results.
14421 * 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
14422 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14423 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14424 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14425 * So drop the bss and continue to next bss.
14426 */
14427 if(chan == NULL)
14428 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014429 hddLog(VOS_TRACE_LEVEL_ERROR,
14430 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14431 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014432 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014433 return NULL;
14434 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014435 /*To keep the rssi icon of the connected AP in the scan window
14436 *and the rssi icon of the wireless networks in sync
14437 * */
14438 if (( eConnectionState_Associated ==
14439 pAdapter->sessionCtx.station.conn_info.connState ) &&
14440 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14441 pAdapter->sessionCtx.station.conn_info.bssId,
14442 WNI_CFG_BSSID_LEN)) &&
14443 (pHddCtx->hdd_wlan_suspended == FALSE))
14444 {
14445 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14446 rssi = (pAdapter->rssi * 100);
14447 }
14448 else
14449 {
14450 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14451 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014452
Nirav Shah20ac06f2013-12-12 18:14:06 +053014453 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014454 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14455 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014456
Jeff Johnson295189b2012-06-20 16:38:30 -070014457 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14458 frame_len, rssi, GFP_KERNEL);
14459 kfree(mgmt);
14460 return bss_status;
14461}
14462
14463/*
14464 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14465 * This function is used to update the BSS data base of CFG8011
14466 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014467struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014468 tCsrRoamInfo *pRoamInfo
14469 )
14470{
14471 tCsrRoamConnectedProfile roamProfile;
14472 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14473 struct cfg80211_bss *bss = NULL;
14474
14475 ENTER();
14476
14477 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14478 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14479
14480 if (NULL != roamProfile.pBssDesc)
14481 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014482 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14483 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014484
14485 if (NULL == bss)
14486 {
14487 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14488 __func__);
14489 }
14490
14491 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14492 }
14493 else
14494 {
14495 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14496 __func__);
14497 }
14498 return bss;
14499}
14500
14501/*
14502 * FUNCTION: wlan_hdd_cfg80211_update_bss
14503 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014504static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14505 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014506 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014507{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014508 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014509 tCsrScanResultInfo *pScanResult;
14510 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014511 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014512 tScanResultHandle pResult;
14513 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014514 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014515 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014517
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014518 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14519 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14520 NO_SESSION, pAdapter->sessionId));
14521
Wilson Yangf80a0542013-10-07 13:02:37 -070014522 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014523 ret = wlan_hdd_validate_context(pHddCtx);
14524 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014526 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014527 }
14528
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014529 if (pAdapter->request != NULL)
14530 {
14531 if ((pAdapter->request->n_ssids == 1)
14532 && (pAdapter->request->ssids != NULL)
14533 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14534 is_p2p_scan = true;
14535 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014536 /*
14537 * start getting scan results and populate cgf80211 BSS database
14538 */
14539 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14540
14541 /* no scan results */
14542 if (NULL == pResult)
14543 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014544 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14545 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014546 wlan_hdd_get_frame_logs(pAdapter,
14547 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014548 return status;
14549 }
14550
14551 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14552
14553 while (pScanResult)
14554 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014555 /*
14556 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14557 * entry already exists in bss data base of cfg80211 for that
14558 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14559 * bss entry instead of cfg80211_inform_bss, But this call expects
14560 * mgmt packet as input. As of now there is no possibility to get
14561 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014562 * ieee80211_mgmt(probe response) and passing to c
14563 * fg80211_inform_bss_frame.
14564 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014565 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14566 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14567 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014568 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14569 continue; //Skip the non p2p bss entries
14570 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014571 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14572 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014573
Jeff Johnson295189b2012-06-20 16:38:30 -070014574
14575 if (NULL == bss_status)
14576 {
14577 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014578 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014579 }
14580 else
14581 {
Yue Maf49ba872013-08-19 12:04:25 -070014582 cfg80211_put_bss(
14583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14584 wiphy,
14585#endif
14586 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014587 }
14588
14589 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14590 }
14591
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014592 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014593 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014594 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014595}
14596
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014597void
14598hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14599{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014600 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014601 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014602} /****** end hddPrintMacAddr() ******/
14603
14604void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014605hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014606{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014607 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014608 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014609 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14610 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14611 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014612} /****** end hddPrintPmkId() ******/
14613
14614//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14615//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14616
14617//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14618//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14619
14620#define dump_bssid(bssid) \
14621 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014622 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14623 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014624 }
14625
14626#define dump_pmkid(pMac, pmkid) \
14627 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014628 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14629 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014630 }
14631
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014632#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014633/*
14634 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14635 * This function is used to notify the supplicant of a new PMKSA candidate.
14636 */
14637int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014638 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014639 int index, bool preauth )
14640{
Jeff Johnsone7245742012-09-05 17:12:55 -070014641#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014642 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014643 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014644
14645 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014646 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014647
14648 if( NULL == pRoamInfo )
14649 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014650 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014651 return -EINVAL;
14652 }
14653
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014654 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14655 {
14656 dump_bssid(pRoamInfo->bssid);
14657 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014658 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014659 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014660#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014661 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014662}
14663#endif //FEATURE_WLAN_LFR
14664
Yue Maef608272013-04-08 23:09:17 -070014665#ifdef FEATURE_WLAN_LFR_METRICS
14666/*
14667 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14668 * 802.11r/LFR metrics reporting function to report preauth initiation
14669 *
14670 */
14671#define MAX_LFR_METRICS_EVENT_LENGTH 100
14672VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14673 tCsrRoamInfo *pRoamInfo)
14674{
14675 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14676 union iwreq_data wrqu;
14677
14678 ENTER();
14679
14680 if (NULL == pAdapter)
14681 {
14682 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14683 return VOS_STATUS_E_FAILURE;
14684 }
14685
14686 /* create the event */
14687 memset(&wrqu, 0, sizeof(wrqu));
14688 memset(metrics_notification, 0, sizeof(metrics_notification));
14689
14690 wrqu.data.pointer = metrics_notification;
14691 wrqu.data.length = scnprintf(metrics_notification,
14692 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14693 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14694
14695 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14696
14697 EXIT();
14698
14699 return VOS_STATUS_SUCCESS;
14700}
14701
14702/*
14703 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14704 * 802.11r/LFR metrics reporting function to report preauth completion
14705 * or failure
14706 */
14707VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14708 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
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 scnprintf(metrics_notification, sizeof(metrics_notification),
14726 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14727 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14728
14729 if (1 == preauth_status)
14730 strncat(metrics_notification, " TRUE", 5);
14731 else
14732 strncat(metrics_notification, " FALSE", 6);
14733
14734 wrqu.data.pointer = metrics_notification;
14735 wrqu.data.length = strlen(metrics_notification);
14736
14737 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14738
14739 EXIT();
14740
14741 return VOS_STATUS_SUCCESS;
14742}
14743
14744/*
14745 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14746 * 802.11r/LFR metrics reporting function to report handover initiation
14747 *
14748 */
14749VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14750 tCsrRoamInfo *pRoamInfo)
14751{
14752 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14753 union iwreq_data wrqu;
14754
14755 ENTER();
14756
14757 if (NULL == pAdapter)
14758 {
14759 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14760 return VOS_STATUS_E_FAILURE;
14761 }
14762
14763 /* create the event */
14764 memset(&wrqu, 0, sizeof(wrqu));
14765 memset(metrics_notification, 0, sizeof(metrics_notification));
14766
14767 wrqu.data.pointer = metrics_notification;
14768 wrqu.data.length = scnprintf(metrics_notification,
14769 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14770 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14771
14772 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14773
14774 EXIT();
14775
14776 return VOS_STATUS_SUCCESS;
14777}
14778#endif
14779
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014780
14781/**
14782 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14783 * @scan_req: scan request to be checked
14784 *
14785 * Return: true or false
14786 */
14787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14788static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14789 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014790 *scan_req, hdd_context_t
14791 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014792{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014793 if (!scan_req || !scan_req->wiphy ||
14794 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014795 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14796 return false;
14797 }
14798 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14799 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14800 return false;
14801 }
14802 return true;
14803}
14804#else
14805static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14806 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014807 *scan_req, hdd_context_t
14808 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014809{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014810 if (!scan_req || !scan_req->wiphy ||
14811 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014812 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14813 return false;
14814 }
14815 return true;
14816}
14817#endif
14818
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14820/**
14821 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14822 * @adapter: Pointer to the adapter
14823 * @req : Scan request
14824 * @aborted : true scan aborted false scan success
14825 *
14826 * This function notifies scan done to cfg80211
14827 *
14828 * Return: none
14829 */
14830static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14831 struct cfg80211_scan_request *req,
14832 bool aborted)
14833{
14834 struct cfg80211_scan_info info = {
14835 .aborted = aborted
14836 };
14837
14838 if (adapter->dev->flags & IFF_UP)
14839 cfg80211_scan_done(req, &info);
14840 else
14841 hddLog(LOGW,
14842 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14843}
14844#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14845/**
14846 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14847 * @adapter: Pointer to the adapter
14848 * @req : Scan request
14849 * @aborted : true scan aborted false scan success
14850 *
14851 * This function notifies scan done to cfg80211
14852 *
14853 * Return: none
14854 */
14855static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14856 struct cfg80211_scan_request *req,
14857 bool aborted)
14858{
14859 if (adapter->dev->flags & IFF_UP)
14860 cfg80211_scan_done(req, aborted);
14861 else
14862 hddLog(LOGW,
14863 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14864}
14865#else
14866/**
14867 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14868 * @adapter: Pointer to the adapter
14869 * @req : Scan request
14870 * @aborted : true scan aborted false scan success
14871 *
14872 * This function notifies scan done to cfg80211
14873 *
14874 * Return: none
14875 */
14876static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14877 struct cfg80211_scan_request *req,
14878 bool aborted)
14879{
14880 cfg80211_scan_done(req, aborted);
14881}
14882#endif
14883
Mukul Sharmab392b642017-08-17 17:45:29 +053014884#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014885/*
14886 * FUNCTION: hdd_cfg80211_scan_done_callback
14887 * scanning callback function, called after finishing scan
14888 *
14889 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014890static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014891 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14892{
14893 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014894 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014896 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 struct cfg80211_scan_request *req = NULL;
14898 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014899 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014900 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014901 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014902
14903 ENTER();
14904
c_manjee1b4ab9a2016-10-26 11:36:55 +053014905 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14906 !pAdapter->dev) {
14907 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14908 return 0;
14909 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014911 if (NULL == pHddCtx) {
14912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014913 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014914 }
14915
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014917 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014918 {
14919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014920 }
14921#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014922 pScanInfo = &pHddCtx->scan_info;
14923
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014925 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014926 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014927 __func__, halHandle, pContext, (int) scanId, (int) status);
14928
Kiet Lamac06e2c2013-10-23 16:25:07 +053014929 pScanInfo->mScanPendingCounter = 0;
14930
Jeff Johnson295189b2012-06-20 16:38:30 -070014931 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014932 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 &pScanInfo->scan_req_completion_event,
14934 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014935 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014936 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014937 hddLog(VOS_TRACE_LEVEL_ERROR,
14938 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014940 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 }
14942
Yue Maef608272013-04-08 23:09:17 -070014943 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014944 {
14945 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014946 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014947 }
14948
14949 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014950 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 {
14952 hddLog(VOS_TRACE_LEVEL_INFO,
14953 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014954 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014955 (int) scanId);
14956 }
14957
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014959 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014960#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014961 {
14962 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14963 pAdapter);
14964 if (0 > ret)
14965 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014966 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014967
Jeff Johnson295189b2012-06-20 16:38:30 -070014968 /* If any client wait scan result through WEXT
14969 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014970 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 {
14972 /* The other scan request waiting for current scan finish
14973 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014974 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014975 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014976 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 }
14978 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014979 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014980 {
14981 struct net_device *dev = pAdapter->dev;
14982 union iwreq_data wrqu;
14983 int we_event;
14984 char *msg;
14985
14986 memset(&wrqu, '\0', sizeof(wrqu));
14987 we_event = SIOCGIWSCAN;
14988 msg = NULL;
14989 wireless_send_event(dev, we_event, &wrqu, msg);
14990 }
14991 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014992 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014993
14994 /* Get the Scan Req */
14995 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014996 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014997
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014998 /* Scan is no longer pending */
14999 pScanInfo->mScanPending = VOS_FALSE;
15000
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053015001 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070015002 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015005 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015006#endif
15007
15008 if (pAdapter->dev) {
15009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15010 pAdapter->dev->name);
15011 }
mukul sharmae7041822015-12-03 15:09:21 +053015012 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015013 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015014 }
15015
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015016 /* last_scan_timestamp is used to decide if new scan
15017 * is needed or not on station interface. If last station
15018 * scan time and new station scan time is less then
15019 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015020 * Also only last_scan_timestamp is updated here last_scan_channellist
15021 * is updated on receiving scan request itself to make sure kernel
15022 * allocated scan request(scan_req) object is not dereferenced here,
15023 * because interface down, where kernel frees scan_req, may happen any
15024 * time while driver is processing scan_done_callback. So it's better
15025 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015026 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015027 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15028 if (status == eCSR_SCAN_SUCCESS)
15029 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15030 else {
15031 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15032 sizeof(pHddCtx->scan_info.last_scan_channelList));
15033 pHddCtx->scan_info.last_scan_numChannels = 0;
15034 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015035 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015036 }
15037
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015038 /*
15039 * cfg80211_scan_done informing NL80211 about completion
15040 * of scanning
15041 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015042 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15043 {
15044 aborted = true;
15045 }
mukul sharmae7041822015-12-03 15:09:21 +053015046
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015048 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15049 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015050#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015051 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015052
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015053 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015054
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015055allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015056 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15057 ) && (pHddCtx->spoofMacAddr.isEnabled
15058 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015059 /* Generate new random mac addr for next scan */
15060 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015061
15062 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15063 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015064 }
15065
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015066 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015067 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015068
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015069 /* Acquire wakelock to handle the case where APP's tries to suspend
15070 * immediatly after the driver gets connect request(i.e after scan)
15071 * from supplicant, this result in app's is suspending and not able
15072 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015073 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015074
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015076 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015077#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015078#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015079 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015080#endif
15081
Jeff Johnson295189b2012-06-20 16:38:30 -070015082 EXIT();
15083 return 0;
15084}
15085
15086/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015087 * FUNCTION: hdd_isConnectionInProgress
15088 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015089 *
15090 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015091v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15092 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015093{
15094 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15095 hdd_station_ctx_t *pHddStaCtx = NULL;
15096 hdd_adapter_t *pAdapter = NULL;
15097 VOS_STATUS status = 0;
15098 v_U8_t staId = 0;
15099 v_U8_t *staMac = NULL;
15100
15101 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15102
15103 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15104 {
15105 pAdapter = pAdapterNode->pAdapter;
15106
15107 if( pAdapter )
15108 {
15109 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015110 "%s: Adapter with device mode %s (%d) exists",
15111 __func__, hdd_device_modetoString(pAdapter->device_mode),
15112 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015113 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015114 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15115 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15116 (eConnectionState_Connecting ==
15117 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15118 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015119 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015120 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015121 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015122 if (session_id && reason)
15123 {
15124 *session_id = pAdapter->sessionId;
15125 *reason = eHDD_CONNECTION_IN_PROGRESS;
15126 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015127 return VOS_TRUE;
15128 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015129 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015130 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015131 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015132 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015133 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015134 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015135 if (session_id && reason)
15136 {
15137 *session_id = pAdapter->sessionId;
15138 *reason = eHDD_REASSOC_IN_PROGRESS;
15139 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015140 return VOS_TRUE;
15141 }
15142 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015143 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15144 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015145 {
15146 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15147 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015148 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15149 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015150 {
15151 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015152 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015153 "%s: client " MAC_ADDRESS_STR
15154 " is in the middle of WPS/EAPOL exchange.", __func__,
15155 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015156 if (session_id && reason)
15157 {
15158 *session_id = pAdapter->sessionId;
15159 *reason = eHDD_EAPOL_IN_PROGRESS;
15160 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015161 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015162 }
15163 }
15164 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15165 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15166 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015167 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15168 ptSapContext pSapCtx = NULL;
15169 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15170 if(pSapCtx == NULL){
15171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15172 FL("psapCtx is NULL"));
15173 return VOS_FALSE;
15174 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015175 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15176 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015177 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15178 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015179 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015180 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015181
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015182 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015183 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15184 "middle of WPS/EAPOL exchange.", __func__,
15185 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015186 if (session_id && reason)
15187 {
15188 *session_id = pAdapter->sessionId;
15189 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15190 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015191 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015192 }
15193 }
15194 }
15195 }
15196 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15197 pAdapterNode = pNext;
15198 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015199 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015200}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015201
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015202/**
15203 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15204 * to the Scan request
15205 * @scanRequest: Pointer to the csr scan request
15206 * @request: Pointer to the scan request from supplicant
15207 *
15208 * Return: None
15209 */
15210#ifdef CFG80211_SCAN_BSSID
15211static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15212 struct cfg80211_scan_request *request)
15213{
15214 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15215}
15216#else
15217static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15218 struct cfg80211_scan_request *request)
15219{
15220}
15221#endif
15222
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015223/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015224 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 * this scan respond to scan trigger and update cfg80211 scan database
15226 * later, scan dump command can be used to recieve scan results
15227 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015228int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015229#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15230 struct net_device *dev,
15231#endif
15232 struct cfg80211_scan_request *request)
15233{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015234 hdd_adapter_t *pAdapter = NULL;
15235 hdd_context_t *pHddCtx = NULL;
15236 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015237 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 tCsrScanRequest scanRequest;
15239 tANI_U8 *channelList = NULL, i;
15240 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015241 int status;
15242 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015244 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015245 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015246 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015247 v_U8_t curr_session_id;
15248 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015249
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015250#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15251 struct net_device *dev = NULL;
15252 if (NULL == request)
15253 {
15254 hddLog(VOS_TRACE_LEVEL_ERROR,
15255 "%s: scan req param null", __func__);
15256 return -EINVAL;
15257 }
15258 dev = request->wdev->netdev;
15259#endif
15260
15261 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15262 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15263 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15264
Jeff Johnson295189b2012-06-20 16:38:30 -070015265 ENTER();
15266
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015267 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15268 __func__, hdd_device_modetoString(pAdapter->device_mode),
15269 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015270
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015271 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015272 if (0 != status)
15273 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015274 return status;
15275 }
15276
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015277 if (NULL == pwextBuf)
15278 {
15279 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15280 __func__);
15281 return -EIO;
15282 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015283 cfg_param = pHddCtx->cfg_ini;
15284 pScanInfo = &pHddCtx->scan_info;
15285
Jeff Johnson295189b2012-06-20 16:38:30 -070015286#ifdef WLAN_BTAMP_FEATURE
15287 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015288 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015289 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015290 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015291 "%s: No scanning when AMP is on", __func__);
15292 return -EOPNOTSUPP;
15293 }
15294#endif
15295 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015296 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015297 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015298 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015299 "%s: Not scanning on device_mode = %s (%d)",
15300 __func__, hdd_device_modetoString(pAdapter->device_mode),
15301 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015302 return -EOPNOTSUPP;
15303 }
15304
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015305 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15306 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15307 return -EOPNOTSUPP;
15308 }
15309
Jeff Johnson295189b2012-06-20 16:38:30 -070015310 if (TRUE == pScanInfo->mScanPending)
15311 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015312 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15313 {
15314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15315 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015316 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015317 }
15318
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015319 // Don't allow scan if PNO scan is going on.
15320 if (pHddCtx->isPnoEnable)
15321 {
15322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15323 FL("pno scan in progress"));
15324 return -EBUSY;
15325 }
15326
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015327 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015328 //Channel and action frame is pending
15329 //Otherwise Cancel Remain On Channel and allow Scan
15330 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015331 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015332 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015333 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015334 return -EBUSY;
15335 }
15336
Jeff Johnson295189b2012-06-20 16:38:30 -070015337 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15338 {
15339 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015340 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015342 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015343 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15344 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015345 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015346 "%s: MAX TM Level Scan not allowed", __func__);
15347 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015348 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015349 }
15350 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15351
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015352 /* Check if scan is allowed at this point of time.
15353 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015354 if (TRUE == pHddCtx->btCoexModeSet)
15355 {
15356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15357 FL("BTCoex Mode operation in progress"));
15358 return -EBUSY;
15359 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015360 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015361 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015362
15363 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15364 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15365 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015366 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15367 pHddCtx->last_scan_reject_reason != curr_reason ||
15368 !pHddCtx->last_scan_reject_timestamp)
15369 {
15370 pHddCtx->last_scan_reject_session_id = curr_session_id;
15371 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015372 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015373 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015374 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015375 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015376 else
15377 {
15378 pHddCtx->scan_reject_cnt++;
15379
Abhishek Singhe4b12562017-06-20 16:53:39 +053015380 if ((pHddCtx->scan_reject_cnt >=
15381 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015382 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015383 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015384 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015385 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015386 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015387 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015388 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015389 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015390 if (pHddCtx->cfg_ini->enableFatalEvent)
15391 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15392 WLAN_LOG_INDICATOR_HOST_DRIVER,
15393 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15394 FALSE, FALSE);
15395 else
15396 {
15397 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015398 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015399 }
15400 }
15401 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015402 return -EBUSY;
15403 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015404 pHddCtx->last_scan_reject_timestamp = 0;
15405 pHddCtx->last_scan_reject_session_id = 0xFF;
15406 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015407 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15410
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015411 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15412 * Becasue of this, driver is assuming that this is not wildcard scan and so
15413 * is not aging out the scan results.
15414 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015415 if ((request->ssids) && (request->n_ssids == 1) &&
15416 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015417 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015418 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015419
15420 if ((request->ssids) && (0 < request->n_ssids))
15421 {
15422 tCsrSSIDInfo *SsidInfo;
15423 int j;
15424 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15425 /* Allocate num_ssid tCsrSSIDInfo structure */
15426 SsidInfo = scanRequest.SSIDs.SSIDList =
15427 ( tCsrSSIDInfo *)vos_mem_malloc(
15428 request->n_ssids*sizeof(tCsrSSIDInfo));
15429
15430 if(NULL == scanRequest.SSIDs.SSIDList)
15431 {
15432 hddLog(VOS_TRACE_LEVEL_ERROR,
15433 "%s: memory alloc failed SSIDInfo buffer", __func__);
15434 return -ENOMEM;
15435 }
15436
15437 /* copy all the ssid's and their length */
15438 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15439 {
15440 /* get the ssid length */
15441 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15442 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15443 SsidInfo->SSID.length);
15444 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15445 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15446 j, SsidInfo->SSID.ssId);
15447 }
15448 /* set the scan type to active */
15449 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15450 }
15451 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015452 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15454 TRACE_CODE_HDD_CFG80211_SCAN,
15455 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015456 /* set the scan type to active */
15457 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015458 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015459 else
15460 {
15461 /*Set the scan type to default type, in this case it is ACTIVE*/
15462 scanRequest.scanType = pScanInfo->scan_mode;
15463 }
15464 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15465 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015466
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015467 csr_scan_request_assign_bssid(&scanRequest, request);
15468
Jeff Johnson295189b2012-06-20 16:38:30 -070015469 /* set BSSType to default type */
15470 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15471
15472 /*TODO: scan the requested channels only*/
15473
15474 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015475 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015476 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015477 hddLog(VOS_TRACE_LEVEL_WARN,
15478 "No of Scan Channels exceeded limit: %d", request->n_channels);
15479 request->n_channels = MAX_CHANNEL;
15480 }
15481
15482 hddLog(VOS_TRACE_LEVEL_INFO,
15483 "No of Scan Channels: %d", request->n_channels);
15484
15485
15486 if( request->n_channels )
15487 {
15488 char chList [(request->n_channels*5)+1];
15489 int len;
15490 channelList = vos_mem_malloc( request->n_channels );
15491 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015492 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015493 hddLog(VOS_TRACE_LEVEL_ERROR,
15494 "%s: memory alloc failed channelList", __func__);
15495 status = -ENOMEM;
15496 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015497 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015498
15499 for( i = 0, len = 0; i < request->n_channels ; i++ )
15500 {
15501 channelList[i] = request->channels[i]->hw_value;
15502 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15503 }
15504
Nirav Shah20ac06f2013-12-12 18:14:06 +053015505 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015506 "Channel-List: %s ", chList);
15507 }
c_hpothu53512302014-04-15 18:49:53 +053015508
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015509 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15510 scanRequest.ChannelInfo.ChannelList = channelList;
15511
15512 /* set requestType to full scan */
15513 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15514
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015515 /* if there is back to back scan happening in driver with in
15516 * nDeferScanTimeInterval interval driver should defer new scan request
15517 * and should provide last cached scan results instead of new channel list.
15518 * This rule is not applicable if scan is p2p scan.
15519 * This condition will work only in case when last request no of channels
15520 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015521 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015522 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015523 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015524
Sushant Kaushik86592172015-04-27 16:35:03 +053015525 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15526 /* if wps ie is NULL , then only defer scan */
15527 if ( pWpsIe == NULL &&
15528 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015529 {
15530 if ( pScanInfo->last_scan_timestamp !=0 &&
15531 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15532 {
15533 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15534 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15535 vos_mem_compare(pScanInfo->last_scan_channelList,
15536 channelList, pScanInfo->last_scan_numChannels))
15537 {
15538 hddLog(VOS_TRACE_LEVEL_WARN,
15539 " New and old station scan time differ is less then %u",
15540 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15541
15542 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015543 pAdapter);
15544
Agarwal Ashish57e84372014-12-05 18:26:53 +053015545 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015546 "Return old cached scan as all channels and no of channels are same");
15547
Agarwal Ashish57e84372014-12-05 18:26:53 +053015548 if (0 > ret)
15549 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015550
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015551 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015552
15553 status = eHAL_STATUS_SUCCESS;
15554 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015555 }
15556 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015557 }
15558
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015559 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15560 * search (Flush on both full scan and social scan but not on single
15561 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15562 */
15563
15564 /* Supplicant does single channel scan after 8-way handshake
15565 * and in that case driver shoudnt flush scan results. If
15566 * driver flushes the scan results here and unfortunately if
15567 * the AP doesnt respond to our probe req then association
15568 * fails which is not desired
15569 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015570 if ((request->n_ssids == 1)
15571 && (request->ssids != NULL)
15572 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15573 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015574
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015575 if( is_p2p_scan ||
15576 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015577 {
15578 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15579 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15580 pAdapter->sessionId );
15581 }
15582
15583 if( request->ie_len )
15584 {
15585 /* save this for future association (join requires this) */
15586 /*TODO: Array needs to be converted to dynamic allocation,
15587 * as multiple ie.s can be sent in cfg80211_scan_request structure
15588 * CR 597966
15589 */
15590 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15591 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15592 pScanInfo->scanAddIE.length = request->ie_len;
15593
15594 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15595 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15596 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015597 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015598 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015599 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015600 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15601 memcpy( pwextBuf->roamProfile.addIEScan,
15602 request->ie, request->ie_len);
15603 }
15604 else
15605 {
15606 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15607 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015608 }
15609
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015610 }
15611 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15612 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15613
15614 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15615 request->ie_len);
15616 if (pP2pIe != NULL)
15617 {
15618#ifdef WLAN_FEATURE_P2P_DEBUG
15619 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15620 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15621 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015622 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015623 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15624 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15625 "Go nego completed to Connection is started");
15626 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15627 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015628 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015629 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15630 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015631 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015632 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15633 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15634 "Disconnected state to Connection is started");
15635 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15636 "for 4way Handshake");
15637 }
15638#endif
15639
15640 /* no_cck will be set during p2p find to disable 11b rates */
15641 if(TRUE == request->no_cck)
15642 {
15643 hddLog(VOS_TRACE_LEVEL_INFO,
15644 "%s: This is a P2P Search", __func__);
15645 scanRequest.p2pSearch = 1;
15646
15647 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015648 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015649 /* set requestType to P2P Discovery */
15650 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15651 }
15652
15653 /*
15654 Skip Dfs Channel in case of P2P Search
15655 if it is set in ini file
15656 */
15657 if(cfg_param->skipDfsChnlInP2pSearch)
15658 {
15659 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015660 }
15661 else
15662 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015663 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015664 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015665
Agarwal Ashish4f616132013-12-30 23:32:50 +053015666 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015667 }
15668 }
15669
15670 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15671
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015672#ifdef FEATURE_WLAN_TDLS
15673 /* if tdls disagree scan right now, return immediately.
15674 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15675 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15676 */
15677 status = wlan_hdd_tdls_scan_callback (pAdapter,
15678 wiphy,
15679#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15680 dev,
15681#endif
15682 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015683 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015684 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015685 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15687 "scan rejected %d", __func__, status);
15688 else
15689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15690 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015691 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015692 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015693 }
15694#endif
15695
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015696 /* acquire the wakelock to avoid the apps suspend during the scan. To
15697 * address the following issues.
15698 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15699 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15700 * for long time, this result in apps running at full power for long time.
15701 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15702 * be stuck in full power because of resume BMPS
15703 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015704 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015705
Nirav Shah20ac06f2013-12-12 18:14:06 +053015706 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15707 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015708 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15709 scanRequest.requestType, scanRequest.scanType,
15710 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015711 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15712
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015713 if (pHddCtx->spoofMacAddr.isEnabled &&
15714 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015715 {
15716 hddLog(VOS_TRACE_LEVEL_INFO,
15717 "%s: MAC Spoofing enabled for current scan", __func__);
15718 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15719 * to fill TxBds for probe request during current scan
15720 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015721 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015722 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015723
15724 if(status != VOS_STATUS_SUCCESS)
15725 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015726 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015727 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015728#ifdef FEATURE_WLAN_TDLS
15729 wlan_hdd_tdls_scan_done_callback(pAdapter);
15730#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015731 goto free_mem;
15732 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015733 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015734 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015735 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015736 pAdapter->sessionId, &scanRequest, &scanId,
15737 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015738
Jeff Johnson295189b2012-06-20 16:38:30 -070015739 if (eHAL_STATUS_SUCCESS != status)
15740 {
15741 hddLog(VOS_TRACE_LEVEL_ERROR,
15742 "%s: sme_ScanRequest returned error %d", __func__, status);
15743 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015744 if(eHAL_STATUS_RESOURCES == status)
15745 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15747 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015748 status = -EBUSY;
15749 } else {
15750 status = -EIO;
15751 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015752 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015753
15754#ifdef FEATURE_WLAN_TDLS
15755 wlan_hdd_tdls_scan_done_callback(pAdapter);
15756#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015757 goto free_mem;
15758 }
15759
15760 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015761 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015762 pAdapter->request = request;
15763 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015764 pScanInfo->no_cck = request->no_cck;
15765 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15766 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15767 pHddCtx->scan_info.last_scan_channelList[i] =
15768 request->channels[i]->hw_value;
15769 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015770
15771 complete(&pScanInfo->scan_req_completion_event);
15772
15773free_mem:
15774 if( scanRequest.SSIDs.SSIDList )
15775 {
15776 vos_mem_free(scanRequest.SSIDs.SSIDList);
15777 }
15778
15779 if( channelList )
15780 vos_mem_free( channelList );
15781
15782 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015783 return status;
15784}
15785
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015786int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15787#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15788 struct net_device *dev,
15789#endif
15790 struct cfg80211_scan_request *request)
15791{
15792 int ret;
15793
15794 vos_ssr_protect(__func__);
15795 ret = __wlan_hdd_cfg80211_scan(wiphy,
15796#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15797 dev,
15798#endif
15799 request);
15800 vos_ssr_unprotect(__func__);
15801
15802 return ret;
15803}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015804
15805void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15806{
15807 v_U8_t iniDot11Mode =
15808 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15809 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15810
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015811 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15812 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015813 switch ( iniDot11Mode )
15814 {
15815 case eHDD_DOT11_MODE_AUTO:
15816 case eHDD_DOT11_MODE_11ac:
15817 case eHDD_DOT11_MODE_11ac_ONLY:
15818#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015819 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15820 sme_IsFeatureSupportedByFW(DOT11AC) )
15821 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15822 else
15823 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015824#else
15825 hddDot11Mode = eHDD_DOT11_MODE_11n;
15826#endif
15827 break;
15828 case eHDD_DOT11_MODE_11n:
15829 case eHDD_DOT11_MODE_11n_ONLY:
15830 hddDot11Mode = eHDD_DOT11_MODE_11n;
15831 break;
15832 default:
15833 hddDot11Mode = iniDot11Mode;
15834 break;
15835 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015836#ifdef WLAN_FEATURE_AP_HT40_24G
15837 if (operationChannel > SIR_11B_CHANNEL_END)
15838#endif
15839 {
15840 /* This call decides required channel bonding mode */
15841 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015842 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015843 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015844 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015845}
15846
Jeff Johnson295189b2012-06-20 16:38:30 -070015847/*
15848 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015849 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015850 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015851int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015852 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15853 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015854{
15855 int status = 0;
15856 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015857 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015858 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015859 v_U32_t roamId;
15860 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015861 eCsrAuthType RSNAuthType;
15862
15863 ENTER();
15864
15865 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015867 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015868
15869 status = wlan_hdd_validate_context(pHddCtx);
15870 if (status)
15871 {
Yue Mae36e3552014-03-05 17:06:20 -080015872 return status;
15873 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015874
Jeff Johnson295189b2012-06-20 16:38:30 -070015875 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15876 {
15877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15878 return -EINVAL;
15879 }
15880
Nitesh Shah9b066282017-06-06 18:05:52 +053015881
Jeff Johnson295189b2012-06-20 16:38:30 -070015882 pRoamProfile = &pWextState->roamProfile;
15883
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015884 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015886 hdd_station_ctx_t *pHddStaCtx;
15887 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015888 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015889
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015890 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15891
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015892 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15894 {
15895 /*QoS not enabled in cfg file*/
15896 pRoamProfile->uapsd_mask = 0;
15897 }
15898 else
15899 {
15900 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015901 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015902 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15903 }
15904
15905 pRoamProfile->SSIDs.numOfSSIDs = 1;
15906 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15907 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015908 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015909 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15910 ssid, ssid_len);
15911
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015912 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15913 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15914
Jeff Johnson295189b2012-06-20 16:38:30 -070015915 if (bssid)
15916 {
15917 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015918 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015919 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015920 /* Save BSSID in seperate variable as well, as RoamProfile
15921 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015922 case of join failure we should send valid BSSID to supplicant
15923 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015924 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015925 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015926
Jeff Johnson295189b2012-06-20 16:38:30 -070015927 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015928 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015929 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015930 /* Store bssid_hint to use in the scan filter. */
15931 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15932 WNI_CFG_BSSID_LEN);
15933 /*
15934 * Save BSSID in seperate variable as well, as RoamProfile
15935 * BSSID is getting zeroed out in the association process. And in
15936 * case of join failure we should send valid BSSID to supplicant
15937 */
15938 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15939 WNI_CFG_BSSID_LEN);
15940 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15941 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015942 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015943
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015944
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015945 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15946 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015947 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15948 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015949 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015950 /*set gen ie*/
15951 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15952 /*set auth*/
15953 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15954 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015955#ifdef FEATURE_WLAN_WAPI
15956 if (pAdapter->wapi_info.nWapiMode)
15957 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015958 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015959 switch (pAdapter->wapi_info.wapiAuthMode)
15960 {
15961 case WAPI_AUTH_MODE_PSK:
15962 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015963 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 pAdapter->wapi_info.wapiAuthMode);
15965 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15966 break;
15967 }
15968 case WAPI_AUTH_MODE_CERT:
15969 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015970 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015971 pAdapter->wapi_info.wapiAuthMode);
15972 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15973 break;
15974 }
15975 } // End of switch
15976 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15977 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15978 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015979 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015980 pRoamProfile->AuthType.numEntries = 1;
15981 pRoamProfile->EncryptionType.numEntries = 1;
15982 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15983 pRoamProfile->mcEncryptionType.numEntries = 1;
15984 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15985 }
15986 }
15987#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015988#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015989 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015990 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15991 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15992 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015993 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15994 sizeof (tSirGtkOffloadParams));
15995 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015996 }
15997#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 pRoamProfile->csrPersona = pAdapter->device_mode;
15999
Jeff Johnson32d95a32012-09-10 13:15:23 -070016000 if( operatingChannel )
16001 {
16002 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16003 pRoamProfile->ChannelInfo.numOfChannels = 1;
16004 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016005 else
16006 {
16007 pRoamProfile->ChannelInfo.ChannelList = NULL;
16008 pRoamProfile->ChannelInfo.numOfChannels = 0;
16009 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016010 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16011 {
16012 hdd_select_cbmode(pAdapter,operatingChannel);
16013 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016014
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016015 /*
16016 * Change conn_state to connecting before sme_RoamConnect(),
16017 * because sme_RoamConnect() has a direct path to call
16018 * hdd_smeRoamCallback(), which will change the conn_state
16019 * If direct path, conn_state will be accordingly changed
16020 * to NotConnected or Associated by either
16021 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16022 * in sme_RoamCallback()
16023 * if sme_RomConnect is to be queued,
16024 * Connecting state will remain until it is completed.
16025 * If connection state is not changed,
16026 * connection state will remain in eConnectionState_NotConnected state.
16027 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16028 * if conn state is eConnectionState_NotConnected.
16029 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16030 * informed of connect result indication which is an issue.
16031 */
16032
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016033 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16034 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016035 {
16036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016037 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016038 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16039 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016040 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16041 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016042 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016043
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016044 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016045 pAdapter->sessionId, pRoamProfile, &roamId);
16046
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016047 if ((eHAL_STATUS_SUCCESS != status) &&
16048 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16049 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016050
16051 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016052 hddLog(VOS_TRACE_LEVEL_ERROR,
16053 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16054 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016055 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016056 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016057 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016058 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016059
16060 pRoamProfile->ChannelInfo.ChannelList = NULL;
16061 pRoamProfile->ChannelInfo.numOfChannels = 0;
16062
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 }
16064 else
16065 {
16066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16067 return -EINVAL;
16068 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016069 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016070 return status;
16071}
16072
16073/*
16074 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16075 * This function is used to set the authentication type (OPEN/SHARED).
16076 *
16077 */
16078static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16079 enum nl80211_auth_type auth_type)
16080{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016081 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016082 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16083
16084 ENTER();
16085
16086 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016087 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016090 hddLog(VOS_TRACE_LEVEL_INFO,
16091 "%s: set authentication type to AUTOSWITCH", __func__);
16092 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16093 break;
16094
16095 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016096#ifdef WLAN_FEATURE_VOWIFI_11R
16097 case NL80211_AUTHTYPE_FT:
16098#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016099 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 "%s: set authentication type to OPEN", __func__);
16101 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16102 break;
16103
16104 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016105 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016106 "%s: set authentication type to SHARED", __func__);
16107 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16108 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016109#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016111 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 "%s: set authentication type to CCKM WPA", __func__);
16113 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16114 break;
16115#endif
16116
16117
16118 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016119 hddLog(VOS_TRACE_LEVEL_ERROR,
16120 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 auth_type);
16122 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16123 return -EINVAL;
16124 }
16125
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016126 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016127 pHddStaCtx->conn_info.authType;
16128 return 0;
16129}
16130
16131/*
16132 * FUNCTION: wlan_hdd_set_akm_suite
16133 * This function is used to set the key mgmt type(PSK/8021x).
16134 *
16135 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016136static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 u32 key_mgmt
16138 )
16139{
16140 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16141 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016142 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016143#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016144#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016145#endif
16146#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016147#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016148#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 /*set key mgmt type*/
16150 switch(key_mgmt)
16151 {
16152 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016153 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016154#ifdef WLAN_FEATURE_VOWIFI_11R
16155 case WLAN_AKM_SUITE_FT_PSK:
16156#endif
16157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 __func__);
16159 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16160 break;
16161
16162 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016163 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016164#ifdef WLAN_FEATURE_VOWIFI_11R
16165 case WLAN_AKM_SUITE_FT_8021X:
16166#endif
16167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016168 __func__);
16169 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16170 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016171#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016172#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16173#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16174 case WLAN_AKM_SUITE_CCKM:
16175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16176 __func__);
16177 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16178 break;
16179#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016180#ifndef WLAN_AKM_SUITE_OSEN
16181#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16182 case WLAN_AKM_SUITE_OSEN:
16183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16184 __func__);
16185 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16186 break;
16187#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016188
16189 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016190 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016191 __func__, key_mgmt);
16192 return -EINVAL;
16193
16194 }
16195 return 0;
16196}
16197
16198/*
16199 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016200 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 * (NONE/WEP40/WEP104/TKIP/CCMP).
16202 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016203static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16204 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016205 bool ucast
16206 )
16207{
16208 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016209 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16211
16212 ENTER();
16213
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016214 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016215 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016216 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016217 __func__, cipher);
16218 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16219 }
16220 else
16221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016222
Jeff Johnson295189b2012-06-20 16:38:30 -070016223 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016224 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016225 {
16226 case IW_AUTH_CIPHER_NONE:
16227 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16228 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016229
Jeff Johnson295189b2012-06-20 16:38:30 -070016230 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016231 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016232 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016233
Jeff Johnson295189b2012-06-20 16:38:30 -070016234 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016235 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016236 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016237
Jeff Johnson295189b2012-06-20 16:38:30 -070016238 case WLAN_CIPHER_SUITE_TKIP:
16239 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16240 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016241
Jeff Johnson295189b2012-06-20 16:38:30 -070016242 case WLAN_CIPHER_SUITE_CCMP:
16243 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16244 break;
16245#ifdef FEATURE_WLAN_WAPI
16246 case WLAN_CIPHER_SUITE_SMS4:
16247 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16248 break;
16249#endif
16250
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016251#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016252 case WLAN_CIPHER_SUITE_KRK:
16253 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16254 break;
16255#endif
16256 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 __func__, cipher);
16259 return -EOPNOTSUPP;
16260 }
16261 }
16262
16263 if (ucast)
16264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016266 __func__, encryptionType);
16267 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16268 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016269 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016270 encryptionType;
16271 }
16272 else
16273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016274 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 __func__, encryptionType);
16276 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16277 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16278 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16279 }
16280
16281 return 0;
16282}
16283
16284
16285/*
16286 * FUNCTION: wlan_hdd_cfg80211_set_ie
16287 * This function is used to parse WPA/RSN IE's.
16288 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016289int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16291 const u8 *ie,
16292#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016293 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016294#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016295 size_t ie_len
16296 )
16297{
16298 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16300 const u8 *genie = ie;
16301#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016302 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016303#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016304 v_U16_t remLen = ie_len;
16305#ifdef FEATURE_WLAN_WAPI
16306 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16307 u16 *tmp;
16308 v_U16_t akmsuiteCount;
16309 int *akmlist;
16310#endif
16311 ENTER();
16312
16313 /* clear previous assocAddIE */
16314 pWextState->assocAddIE.length = 0;
16315 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016316 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016317
16318 while (remLen >= 2)
16319 {
16320 v_U16_t eLen = 0;
16321 v_U8_t elementId;
16322 elementId = *genie++;
16323 eLen = *genie++;
16324 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016325
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016326 /* Sanity check on eLen */
16327 if (eLen > remLen) {
16328 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16329 __func__, eLen, elementId);
16330 VOS_ASSERT(0);
16331 return -EINVAL;
16332 }
16333
Arif Hussain6d2a3322013-11-17 19:50:10 -080016334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016335 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016336
16337 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016339 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016340 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 -070016341 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016342 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016343 "%s: Invalid WPA IE", __func__);
16344 return -EINVAL;
16345 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016346 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016347 {
16348 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016349 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016350 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016351
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016352 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016353 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016354 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16355 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016356 VOS_ASSERT(0);
16357 return -ENOMEM;
16358 }
16359 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16360 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16361 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016362
Jeff Johnson295189b2012-06-20 16:38:30 -070016363 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16364 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16365 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16366 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016367 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16368 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016369 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16370 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16371 __func__, eLen);
16372 VOS_ASSERT(0);
16373 return -EINVAL;
16374 }
16375
Jeff Johnson295189b2012-06-20 16:38:30 -070016376 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16377 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16378 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16379 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16380 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16381 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016382 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016383 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016384 {
16385 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016386 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016387 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016388
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016389 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016390 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016391 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16392 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016393 VOS_ASSERT(0);
16394 return -ENOMEM;
16395 }
16396 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16397 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16398 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016399
Jeff Johnson295189b2012-06-20 16:38:30 -070016400 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16401 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16402 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016403#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016404 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16405 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016406 /*Consider WFD IE, only for P2P Client */
16407 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16408 {
16409 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016410 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016411 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016412
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016413 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016414 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016415 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16416 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016417 VOS_ASSERT(0);
16418 return -ENOMEM;
16419 }
16420 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16421 // WPS IE + P2P IE + WFD IE
16422 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16423 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016424
Jeff Johnson295189b2012-06-20 16:38:30 -070016425 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16426 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16427 }
16428#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016429 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016430 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016431 HS20_OUI_TYPE_SIZE)) )
16432 {
16433 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016434 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016435 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016436
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016437 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016438 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016439 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16440 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016441 VOS_ASSERT(0);
16442 return -ENOMEM;
16443 }
16444 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16445 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016446
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016447 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16448 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16449 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016450 /* Appending OSEN Information Element in Assiciation Request */
16451 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16452 OSEN_OUI_TYPE_SIZE)) )
16453 {
16454 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16455 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16456 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016457
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016458 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016459 {
16460 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16461 "Need bigger buffer space");
16462 VOS_ASSERT(0);
16463 return -ENOMEM;
16464 }
16465 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16466 pWextState->assocAddIE.length += eLen + 2;
16467
16468 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16469 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16470 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16471 }
16472
Abhishek Singh4322e622015-06-10 15:42:54 +053016473 /* Update only for WPA IE */
16474 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16475 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016476
16477 /* populating as ADDIE in beacon frames */
16478 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016479 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016480 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16481 {
16482 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16483 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16484 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16485 {
16486 hddLog(LOGE,
16487 "Coldn't pass "
16488 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16489 }
16490 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16491 else
16492 hddLog(LOGE,
16493 "Could not pass on "
16494 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16495
16496 /* IBSS mode doesn't contain params->proberesp_ies still
16497 beaconIE's need to be populated in probe response frames */
16498 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16499 {
16500 u16 rem_probe_resp_ie_len = eLen + 2;
16501 u8 probe_rsp_ie_len[3] = {0};
16502 u8 counter = 0;
16503
16504 /* Check Probe Resp Length if it is greater then 255 then
16505 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16506 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16507 not able Store More then 255 bytes into One Variable */
16508
16509 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16510 {
16511 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16512 {
16513 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16514 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16515 }
16516 else
16517 {
16518 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16519 rem_probe_resp_ie_len = 0;
16520 }
16521 }
16522
16523 rem_probe_resp_ie_len = 0;
16524
16525 if (probe_rsp_ie_len[0] > 0)
16526 {
16527 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16528 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16529 (tANI_U8*)(genie - 2),
16530 probe_rsp_ie_len[0], NULL,
16531 eANI_BOOLEAN_FALSE)
16532 == eHAL_STATUS_FAILURE)
16533 {
16534 hddLog(LOGE,
16535 "Could not pass"
16536 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16537 }
16538 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16539 }
16540
16541 if (probe_rsp_ie_len[1] > 0)
16542 {
16543 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16544 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16545 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16546 probe_rsp_ie_len[1], NULL,
16547 eANI_BOOLEAN_FALSE)
16548 == eHAL_STATUS_FAILURE)
16549 {
16550 hddLog(LOGE,
16551 "Could not pass"
16552 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16553 }
16554 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16555 }
16556
16557 if (probe_rsp_ie_len[2] > 0)
16558 {
16559 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16560 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16561 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16562 probe_rsp_ie_len[2], NULL,
16563 eANI_BOOLEAN_FALSE)
16564 == eHAL_STATUS_FAILURE)
16565 {
16566 hddLog(LOGE,
16567 "Could not pass"
16568 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16569 }
16570 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16571 }
16572
16573 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16574 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16575 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16576 {
16577 hddLog(LOGE,
16578 "Could not pass"
16579 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16580 }
16581 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016582 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016583 break;
16584 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016585 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16586 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16587 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16588 VOS_ASSERT(0);
16589 return -EINVAL;
16590 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016591 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16592 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16593 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16594 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16595 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16596 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016597
Abhishek Singhb16f3562016-01-20 11:08:32 +053016598 /* Appending extended capabilities with Interworking or
16599 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016600 *
16601 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016602 * interworkingService or bsstransition bit is set to 1.
16603 * Driver is only interested in interworkingService and
16604 * bsstransition capability from supplicant.
16605 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016606 * required from supplicat, it needs to be handled while
16607 * sending Assoc Req in LIM.
16608 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016609 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016610 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016611 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016612 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016613 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016614
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016615 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016616 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016617 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16618 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016619 VOS_ASSERT(0);
16620 return -ENOMEM;
16621 }
16622 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16623 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016624
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016625 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16626 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16627 break;
16628 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016629#ifdef FEATURE_WLAN_WAPI
16630 case WLAN_EID_WAPI:
16631 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016632 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 pAdapter->wapi_info.nWapiMode);
16634 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016635 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016636 akmsuiteCount = WPA_GET_LE16(tmp);
16637 tmp = tmp + 1;
16638 akmlist = (int *)(tmp);
16639 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16640 {
16641 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16642 }
16643 else
16644 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016645 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016646 VOS_ASSERT(0);
16647 return -EINVAL;
16648 }
16649
16650 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16651 {
16652 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016653 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016654 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016655 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016656 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016657 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016659 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016660 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16661 }
16662 break;
16663#endif
16664 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016665 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016666 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016667 /* when Unknown IE is received we should break and continue
16668 * to the next IE in the buffer instead we were returning
16669 * so changing this to break */
16670 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016671 }
16672 genie += eLen;
16673 remLen -= eLen;
16674 }
16675 EXIT();
16676 return 0;
16677}
16678
16679/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016680 * FUNCTION: hdd_isWPAIEPresent
16681 * Parse the received IE to find the WPA IE
16682 *
16683 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016684static bool hdd_isWPAIEPresent(
16685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16686 const u8 *ie,
16687#else
16688 u8 *ie,
16689#endif
16690 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016691{
16692 v_U8_t eLen = 0;
16693 v_U16_t remLen = ie_len;
16694 v_U8_t elementId = 0;
16695
16696 while (remLen >= 2)
16697 {
16698 elementId = *ie++;
16699 eLen = *ie++;
16700 remLen -= 2;
16701 if (eLen > remLen)
16702 {
16703 hddLog(VOS_TRACE_LEVEL_ERROR,
16704 "%s: IE length is wrong %d", __func__, eLen);
16705 return FALSE;
16706 }
16707 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16708 {
16709 /* OUI - 0x00 0X50 0XF2
16710 WPA Information Element - 0x01
16711 WPA version - 0x01*/
16712 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16713 return TRUE;
16714 }
16715 ie += eLen;
16716 remLen -= eLen;
16717 }
16718 return FALSE;
16719}
16720
16721/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016723 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016724 * parameters during connect operation.
16725 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016726int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016727 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016728 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016729{
16730 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016731 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016732 ENTER();
16733
16734 /*set wpa version*/
16735 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16736
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016737 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016738 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016739 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016740 {
16741 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16742 }
16743 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16744 {
16745 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16746 }
16747 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016748
16749 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016750 pWextState->wpaVersion);
16751
16752 /*set authentication type*/
16753 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16754
16755 if (0 > status)
16756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016757 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016758 "%s: failed to set authentication type ", __func__);
16759 return status;
16760 }
16761
16762 /*set key mgmt type*/
16763 if (req->crypto.n_akm_suites)
16764 {
16765 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16766 if (0 > status)
16767 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016769 __func__);
16770 return status;
16771 }
16772 }
16773
16774 /*set pairwise cipher type*/
16775 if (req->crypto.n_ciphers_pairwise)
16776 {
16777 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16778 req->crypto.ciphers_pairwise[0], true);
16779 if (0 > status)
16780 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016781 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016782 "%s: failed to set unicast cipher type", __func__);
16783 return status;
16784 }
16785 }
16786 else
16787 {
16788 /*Reset previous cipher suite to none*/
16789 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
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 unicast cipher type", __func__);
16794 return status;
16795 }
16796 }
16797
16798 /*set group cipher type*/
16799 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16800 false);
16801
16802 if (0 > status)
16803 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016805 __func__);
16806 return status;
16807 }
16808
Chet Lanctot186b5732013-03-18 10:26:30 -070016809#ifdef WLAN_FEATURE_11W
16810 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16811#endif
16812
Jeff Johnson295189b2012-06-20 16:38:30 -070016813 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16814 if (req->ie_len)
16815 {
16816 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16817 if ( 0 > status)
16818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016820 __func__);
16821 return status;
16822 }
16823 }
16824
16825 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016826 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016827 {
16828 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16829 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16830 )
16831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016832 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16834 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016836 __func__);
16837 return -EOPNOTSUPP;
16838 }
16839 else
16840 {
16841 u8 key_len = req->key_len;
16842 u8 key_idx = req->key_idx;
16843
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016844 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016845 && (CSR_MAX_NUM_KEY > key_idx)
16846 )
16847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016848 hddLog(VOS_TRACE_LEVEL_INFO,
16849 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016850 __func__, key_idx, key_len);
16851 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016852 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016853 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016854 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016855 (u8)key_len;
16856 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16857 }
16858 }
16859 }
16860 }
16861
16862 return status;
16863}
16864
16865/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016866 * FUNCTION: wlan_hdd_try_disconnect
16867 * This function is used to disconnect from previous
16868 * connection
16869 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016870int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016871{
16872 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016873 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016874 hdd_station_ctx_t *pHddStaCtx;
16875 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016876 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016877
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016878 ret = wlan_hdd_validate_context(pHddCtx);
16879 if (0 != ret)
16880 {
16881 return ret;
16882 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016883 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16884
16885 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16886
16887 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16888 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016889 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016890 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16891 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016892 /* Indicate disconnect to SME so that in-progress connection or preauth
16893 * can be aborted
16894 */
16895 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16896 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016897 spin_lock_bh(&pAdapter->lock_for_active_session);
16898 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16899 {
16900 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16901 }
16902 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016903 hdd_connSetConnectionState(pHddStaCtx,
16904 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016905 /* Issue disconnect to CSR */
16906 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016907 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016908 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016909 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16910 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16911 hddLog(LOG1,
16912 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16913 } else if ( 0 != status ) {
16914 hddLog(LOGE,
16915 FL("csrRoamDisconnect failure, returned %d"),
16916 (int)status );
16917 result = -EINVAL;
16918 goto disconnected;
16919 }
16920 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016921 &pAdapter->disconnect_comp_var,
16922 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016923 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16924 hddLog(LOGE,
16925 "%s: Failed to disconnect, timed out", __func__);
16926 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016927 }
16928 }
16929 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16930 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016931 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016932 &pAdapter->disconnect_comp_var,
16933 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016934 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016935 {
16936 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016937 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016938 }
16939 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016940disconnected:
16941 hddLog(LOG1,
16942 FL("Set HDD connState to eConnectionState_NotConnected"));
16943 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16944 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016945}
16946
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016947/**
16948 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16949 * @adapter: Pointer to the HDD adapter
16950 * @req: Pointer to the structure cfg_connect_params receieved from user space
16951 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053016952 * This function will start reassociation if prev_bssid is set and bssid/
16953 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016954 *
16955 * Return: success if reassociation is happening
16956 * Error code if reassociation is not permitted or not happening
16957 */
16958#ifdef CFG80211_CONNECT_PREV_BSSID
16959static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16960 struct cfg80211_connect_params *req)
16961{
16962 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053016963 const uint8_t *bssid = NULL;
16964 uint16_t channel = 0;
16965
16966 if (req->bssid)
16967 bssid = req->bssid;
16968 else if (req->bssid_hint)
16969 bssid = req->bssid_hint;
16970
16971 if (req->channel)
16972 channel = req->channel->hw_value;
16973 else if (req->channel_hint)
16974 channel = req->channel_hint->hw_value;
16975
16976 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016977 hddLog(VOS_TRACE_LEVEL_INFO,
16978 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053016979 channel, MAC_ADDR_ARRAY(bssid));
16980 status = hdd_reassoc(adapter, bssid, channel,
16981 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016982 }
16983 return status;
16984}
16985#else
16986static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16987 struct cfg80211_connect_params *req)
16988{
16989 return -EPERM;
16990}
16991#endif
16992
Abhishek Singhe3beee22017-07-31 15:35:40 +053016993/**
16994 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16995 * connect in HT20 mode
16996 * @hdd_ctx: hdd context
16997 * @adapter: Pointer to the HDD adapter
16998 * @req: Pointer to the structure cfg_connect_params receieved from user space
16999 *
17000 * This function will check if supplicant has indicated to to connect in HT20
17001 * mode. this is currently applicable only for 2.4Ghz mode only.
17002 * if feature is enabled and supplicant indicate HT20 set
17003 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17004 *
17005 * Return: void
17006 */
17007#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17008static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17009 hdd_adapter_t *adapter,
17010 struct cfg80211_connect_params *req)
17011{
17012 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17013 tCsrRoamProfile *roam_profile;
17014
17015 roam_profile = &wext_state->roamProfile;
17016 roam_profile->force_24ghz_in_ht20 = false;
17017 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17018 !(req->ht_capa.cap_info &
17019 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17020 roam_profile->force_24ghz_in_ht20 = true;
17021
17022 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17023 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17024}
17025#else
17026static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17027 hdd_adapter_t *adapter,
17028 struct cfg80211_connect_params *req)
17029{
17030 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17031 tCsrRoamProfile *roam_profile;
17032
17033 roam_profile = &wext_state->roamProfile;
17034 roam_profile->force_24ghz_in_ht20 = false;
17035}
17036#endif
17037
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017038/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017039 * FUNCTION: __wlan_hdd_cfg80211_connect
17040 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017041 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017042static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017043 struct net_device *ndev,
17044 struct cfg80211_connect_params *req
17045 )
17046{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017047 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017048 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017049#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17050 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017051 const u8 *bssid_hint = req->bssid_hint;
17052#else
17053 const u8 *bssid_hint = NULL;
17054#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017055 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017056 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017057 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017058
17059 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017060
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017061 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17062 TRACE_CODE_HDD_CFG80211_CONNECT,
17063 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017064 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017065 "%s: device_mode = %s (%d)", __func__,
17066 hdd_device_modetoString(pAdapter->device_mode),
17067 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017068
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017069 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017070 if (!pHddCtx)
17071 {
17072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17073 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017074 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017075 }
17076
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017077 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017078 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017079 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017080 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017081 }
17082
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017083 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17084 return -EINVAL;
17085
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017086 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17087 if (0 == status)
17088 return status;
17089
Agarwal Ashish51325b52014-06-16 16:50:49 +053017090
Jeff Johnson295189b2012-06-20 16:38:30 -070017091#ifdef WLAN_BTAMP_FEATURE
17092 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017093 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017094 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017095 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017096 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017097 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017098 }
17099#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017100
17101 //If Device Mode is Station Concurrent Sessions Exit BMps
17102 //P2P Mode will be taken care in Open/close adapter
17103 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017104 (vos_concurrent_open_sessions_running())) {
17105 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17106 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017107 }
17108
17109 /*Try disconnecting if already in connected state*/
17110 status = wlan_hdd_try_disconnect(pAdapter);
17111 if ( 0 > status)
17112 {
17113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17114 " connection"));
17115 return -EALREADY;
17116 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017117 /* Check for max concurrent connections after doing disconnect if any*/
17118 if (vos_max_concurrent_connections_reached()) {
17119 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17120 return -ECONNREFUSED;
17121 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017122
Jeff Johnson295189b2012-06-20 16:38:30 -070017123 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017124 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017125
17126 if ( 0 > status)
17127 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017128 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017129 __func__);
17130 return status;
17131 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017132
17133 if (pHddCtx->spoofMacAddr.isEnabled)
17134 {
17135 hddLog(VOS_TRACE_LEVEL_INFO,
17136 "%s: MAC Spoofing enabled ", __func__);
17137 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17138 * to fill TxBds for probe request during SSID scan which may happen
17139 * as part of connect command
17140 */
17141 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17142 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17143 if (status != VOS_STATUS_SUCCESS)
17144 return -ECONNREFUSED;
17145 }
17146
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017147 if (req->channel)
17148 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017149 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017150 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017151
17152 /* Abort if any scan is going on */
17153 status = wlan_hdd_scan_abort(pAdapter);
17154 if (0 != status)
17155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17156
Abhishek Singhe3beee22017-07-31 15:35:40 +053017157 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17158
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017159 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17160 req->ssid_len, req->bssid,
17161 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017162
Sushant Kaushikd7083982015-03-18 14:33:24 +053017163 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017164 {
17165 //ReEnable BMPS if disabled
17166 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17167 (NULL != pHddCtx))
17168 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017169 if (pHddCtx->hdd_wlan_suspended)
17170 {
17171 hdd_set_pwrparams(pHddCtx);
17172 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017173 //ReEnable Bmps and Imps back
17174 hdd_enable_bmps_imps(pHddCtx);
17175 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 return status;
17178 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017179 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017180 EXIT();
17181 return status;
17182}
17183
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017184static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17185 struct net_device *ndev,
17186 struct cfg80211_connect_params *req)
17187{
17188 int ret;
17189 vos_ssr_protect(__func__);
17190 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17191 vos_ssr_unprotect(__func__);
17192
17193 return ret;
17194}
Jeff Johnson295189b2012-06-20 16:38:30 -070017195
17196/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017197 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017198 * This function is used to issue a disconnect request to SME
17199 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017200static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017201 struct net_device *dev,
17202 u16 reason
17203 )
17204{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017206 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017207 tCsrRoamProfile *pRoamProfile;
17208 hdd_station_ctx_t *pHddStaCtx;
17209 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017210#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017211 tANI_U8 staIdx;
17212#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017213
Jeff Johnson295189b2012-06-20 16:38:30 -070017214 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017215
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017216 if (!pAdapter) {
17217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17218 return -EINVAL;
17219 }
17220
17221 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17222 if (!pHddStaCtx) {
17223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17224 return -EINVAL;
17225 }
17226
17227 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17228 status = wlan_hdd_validate_context(pHddCtx);
17229 if (0 != status)
17230 {
17231 return status;
17232 }
17233
17234 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17235
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017236 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17237 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17238 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017239 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17240 __func__, hdd_device_modetoString(pAdapter->device_mode),
17241 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017242
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017243 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17244 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017245
Jeff Johnson295189b2012-06-20 16:38:30 -070017246 if (NULL != pRoamProfile)
17247 {
17248 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017249 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17250 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017251 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017252 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017253 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017254 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017255 switch(reason)
17256 {
17257 case WLAN_REASON_MIC_FAILURE:
17258 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17259 break;
17260
17261 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17262 case WLAN_REASON_DISASSOC_AP_BUSY:
17263 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17264 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17265 break;
17266
17267 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17268 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017269 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017270 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17271 break;
17272
Jeff Johnson295189b2012-06-20 16:38:30 -070017273 default:
17274 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17275 break;
17276 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017277 pScanInfo = &pHddCtx->scan_info;
17278 if (pScanInfo->mScanPending)
17279 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017280 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017281 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017282 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017283 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017284 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017285 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017286#ifdef FEATURE_WLAN_TDLS
17287 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017288 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017289 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017290 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17291 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017292 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017293 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017294 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017296 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017297 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017298 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017299 status = sme_DeleteTdlsPeerSta(
17300 WLAN_HDD_GET_HAL_CTX(pAdapter),
17301 pAdapter->sessionId,
17302 mac);
17303 if (status != eHAL_STATUS_SUCCESS) {
17304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17305 return -EPERM;
17306 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017307 }
17308 }
17309#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017310
17311 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17312 reasonCode,
17313 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017314 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17315 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017316 {
17317 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017318 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017319 __func__, (int)status );
17320 return -EINVAL;
17321 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017322 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017323 else
17324 {
17325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17326 "called while in %d state", __func__,
17327 pHddStaCtx->conn_info.connState);
17328 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017329 }
17330 else
17331 {
17332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17333 }
17334
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017335 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017336 return status;
17337}
17338
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017339static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17340 struct net_device *dev,
17341 u16 reason
17342 )
17343{
17344 int ret;
17345 vos_ssr_protect(__func__);
17346 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17347 vos_ssr_unprotect(__func__);
17348
17349 return ret;
17350}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017351
Jeff Johnson295189b2012-06-20 16:38:30 -070017352/*
17353 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017354 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017355 * settings in IBSS mode.
17356 */
17357static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017358 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017359 struct cfg80211_ibss_params *params
17360 )
17361{
17362 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017363 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017364 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017365 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17366 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017367
Jeff Johnson295189b2012-06-20 16:38:30 -070017368 ENTER();
17369
17370 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017371 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017372
17373 if (params->ie_len && ( NULL != params->ie) )
17374 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017375 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17376 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017377 {
17378 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17379 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17380 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017381 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017382 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017383 tDot11fIEWPA dot11WPAIE;
17384 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017385 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017386
Wilson Yang00256342013-10-10 23:13:38 -070017387 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017388 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17389 params->ie_len, DOT11F_EID_WPA);
17390 if ( NULL != ie )
17391 {
17392 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017393
17394 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17395 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17396 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17397 return -EINVAL;
17398 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017399 // Unpack the WPA IE
17400 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017401 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017402 &ie[2+4],
17403 ie[1] - 4,
17404 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017405 if (DOT11F_FAILED(ret))
17406 {
17407 hddLog(LOGE,
17408 FL("unpack failed status:(0x%08x)"),
17409 ret);
17410 return -EINVAL;
17411 }
17412
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017413 /*Extract the multicast cipher, the encType for unicast
17414 cipher for wpa-none is none*/
17415 encryptionType =
17416 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17417 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017418 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017419
Jeff Johnson295189b2012-06-20 16:38:30 -070017420 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17421
17422 if (0 > status)
17423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017425 __func__);
17426 return status;
17427 }
17428 }
17429
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017430 pWextState->roamProfile.AuthType.authType[0] =
17431 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 if (params->privacy)
17434 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017435 /* Security enabled IBSS, At this time there is no information available
17436 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017437 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017438 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017439 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017440 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017441 *enable privacy bit in beacons */
17442
17443 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17444 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017445 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17446 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017447 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17448 pWextState->roamProfile.EncryptionType.numEntries = 1;
17449 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017450 return status;
17451}
17452
17453/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017454 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017455 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017456 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017457static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017458 struct net_device *dev,
17459 struct cfg80211_ibss_params *params
17460 )
17461{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017463 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17464 tCsrRoamProfile *pRoamProfile;
17465 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017466 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17467 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017468 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017469
17470 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017471
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017472 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17473 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17474 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017475 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017476 "%s: device_mode = %s (%d)", __func__,
17477 hdd_device_modetoString(pAdapter->device_mode),
17478 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017479
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017480 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017481 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017482 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017483 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017484 }
17485
17486 if (NULL == pWextState)
17487 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017488 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017489 __func__);
17490 return -EIO;
17491 }
17492
Agarwal Ashish51325b52014-06-16 16:50:49 +053017493 if (vos_max_concurrent_connections_reached()) {
17494 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17495 return -ECONNREFUSED;
17496 }
17497
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017498 /*Try disconnecting if already in connected state*/
17499 status = wlan_hdd_try_disconnect(pAdapter);
17500 if ( 0 > status)
17501 {
17502 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17503 " IBSS connection"));
17504 return -EALREADY;
17505 }
17506
Jeff Johnson295189b2012-06-20 16:38:30 -070017507 pRoamProfile = &pWextState->roamProfile;
17508
17509 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017511 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017512 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017513 return -EINVAL;
17514 }
17515
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017516 /* BSSID is provided by upper layers hence no need to AUTO generate */
17517 if (NULL != params->bssid) {
17518 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17519 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17520 hddLog (VOS_TRACE_LEVEL_ERROR,
17521 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17522 return -EIO;
17523 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017524 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017525 }
krunal sonie9002db2013-11-25 14:24:17 -080017526 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17527 {
17528 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17529 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17530 {
17531 hddLog (VOS_TRACE_LEVEL_ERROR,
17532 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17533 return -EIO;
17534 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017535
17536 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017537 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017538 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017539 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017540
Jeff Johnson295189b2012-06-20 16:38:30 -070017541 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017542 if (NULL !=
17543#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17544 params->chandef.chan)
17545#else
17546 params->channel)
17547#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017548 {
17549 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017550 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17551 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17552 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17553 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017554
17555 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017556 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017557 ieee80211_frequency_to_channel(
17558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17559 params->chandef.chan->center_freq);
17560#else
17561 params->channel->center_freq);
17562#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017563
17564 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17565 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017566 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17568 __func__);
17569 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017570 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017571
17572 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017573 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017574 if (channelNum == validChan[indx])
17575 {
17576 break;
17577 }
17578 }
17579 if (indx >= numChans)
17580 {
17581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017582 __func__, channelNum);
17583 return -EINVAL;
17584 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017585 /* Set the Operational Channel */
17586 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17587 channelNum);
17588 pRoamProfile->ChannelInfo.numOfChannels = 1;
17589 pHddStaCtx->conn_info.operationChannel = channelNum;
17590 pRoamProfile->ChannelInfo.ChannelList =
17591 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017592 }
17593
17594 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017595 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017596 if (status < 0)
17597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017599 __func__);
17600 return status;
17601 }
17602
17603 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017604 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017605 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017606 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017607
17608 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017610
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017611 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017612 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017613}
17614
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017615static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17616 struct net_device *dev,
17617 struct cfg80211_ibss_params *params
17618 )
17619{
17620 int ret = 0;
17621
17622 vos_ssr_protect(__func__);
17623 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17624 vos_ssr_unprotect(__func__);
17625
17626 return ret;
17627}
17628
Jeff Johnson295189b2012-06-20 16:38:30 -070017629/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017630 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017631 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017632 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017633static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 struct net_device *dev
17635 )
17636{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017638 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17639 tCsrRoamProfile *pRoamProfile;
17640 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017641 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017642 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017643#ifdef WLAN_FEATURE_RMC
17644 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17645#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017646
17647 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017649 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17650 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17651 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017652 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017653 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017654 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017655 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017656 }
17657
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17659 hdd_device_modetoString(pAdapter->device_mode),
17660 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017661 if (NULL == pWextState)
17662 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017663 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017664 __func__);
17665 return -EIO;
17666 }
17667
17668 pRoamProfile = &pWextState->roamProfile;
17669
17670 /* Issue disconnect only if interface type is set to IBSS */
17671 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17672 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017673 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017674 __func__);
17675 return -EINVAL;
17676 }
17677
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017678#ifdef WLAN_FEATURE_RMC
17679 /* Clearing add IE of beacon */
17680 if (ccmCfgSetStr(pHddCtx->hHal,
17681 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17682 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17683 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17684 {
17685 hddLog (VOS_TRACE_LEVEL_ERROR,
17686 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17687 return -EINVAL;
17688 }
17689 if (ccmCfgSetInt(pHddCtx->hHal,
17690 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17691 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17692 {
17693 hddLog (VOS_TRACE_LEVEL_ERROR,
17694 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17695 __func__);
17696 return -EINVAL;
17697 }
17698
17699 // Reset WNI_CFG_PROBE_RSP Flags
17700 wlan_hdd_reset_prob_rspies(pAdapter);
17701
17702 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17703 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17704 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17705 {
17706 hddLog (VOS_TRACE_LEVEL_ERROR,
17707 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17708 __func__);
17709 return -EINVAL;
17710 }
17711#endif
17712
Jeff Johnson295189b2012-06-20 16:38:30 -070017713 /* Issue Disconnect request */
17714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017715 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17716 pAdapter->sessionId,
17717 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17718 if (!HAL_STATUS_SUCCESS(hal_status)) {
17719 hddLog(LOGE,
17720 FL("sme_RoamDisconnect failed hal_status(%d)"),
17721 hal_status);
17722 return -EAGAIN;
17723 }
17724 status = wait_for_completion_timeout(
17725 &pAdapter->disconnect_comp_var,
17726 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17727 if (!status) {
17728 hddLog(LOGE,
17729 FL("wait on disconnect_comp_var failed"));
17730 return -ETIMEDOUT;
17731 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017733 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017734 return 0;
17735}
17736
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017737static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17738 struct net_device *dev
17739 )
17740{
17741 int ret = 0;
17742
17743 vos_ssr_protect(__func__);
17744 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17745 vos_ssr_unprotect(__func__);
17746
17747 return ret;
17748}
17749
Jeff Johnson295189b2012-06-20 16:38:30 -070017750/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017751 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017752 * This function is used to set the phy parameters
17753 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17754 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017755static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017756 u32 changed)
17757{
17758 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17759 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017760 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017761
17762 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017763
17764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017765 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17766 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017769 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017772 }
17773
Jeff Johnson295189b2012-06-20 16:38:30 -070017774 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17775 {
17776 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17777 WNI_CFG_RTS_THRESHOLD_STAMAX :
17778 wiphy->rts_threshold;
17779
17780 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017781 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017783 hddLog(VOS_TRACE_LEVEL_ERROR,
17784 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017785 __func__, rts_threshold);
17786 return -EINVAL;
17787 }
17788
17789 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17790 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017791 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017792 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017793 hddLog(VOS_TRACE_LEVEL_ERROR,
17794 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017795 __func__, rts_threshold);
17796 return -EIO;
17797 }
17798
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017799 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017800 rts_threshold);
17801 }
17802
17803 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17804 {
17805 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17806 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17807 wiphy->frag_threshold;
17808
17809 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017810 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017812 hddLog(VOS_TRACE_LEVEL_ERROR,
17813 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017814 frag_threshold);
17815 return -EINVAL;
17816 }
17817
17818 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17819 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017820 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017822 hddLog(VOS_TRACE_LEVEL_ERROR,
17823 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017824 __func__, frag_threshold);
17825 return -EIO;
17826 }
17827
17828 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17829 frag_threshold);
17830 }
17831
17832 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17833 || (changed & WIPHY_PARAM_RETRY_LONG))
17834 {
17835 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17836 wiphy->retry_short :
17837 wiphy->retry_long;
17838
17839 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17840 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017843 __func__, retry_value);
17844 return -EINVAL;
17845 }
17846
17847 if (changed & WIPHY_PARAM_RETRY_SHORT)
17848 {
17849 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17850 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017851 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017852 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017853 hddLog(VOS_TRACE_LEVEL_ERROR,
17854 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017855 __func__, retry_value);
17856 return -EIO;
17857 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017858 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017859 __func__, retry_value);
17860 }
17861 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17862 {
17863 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17864 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017865 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017867 hddLog(VOS_TRACE_LEVEL_ERROR,
17868 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017869 __func__, retry_value);
17870 return -EIO;
17871 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017872 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017873 __func__, retry_value);
17874 }
17875 }
17876
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017877 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017878 return 0;
17879}
17880
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017881static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17882 u32 changed)
17883{
17884 int ret;
17885
17886 vos_ssr_protect(__func__);
17887 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17888 vos_ssr_unprotect(__func__);
17889
17890 return ret;
17891}
17892
Jeff Johnson295189b2012-06-20 16:38:30 -070017893/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017894 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017895 * This function is used to set the txpower
17896 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017897static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017898#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17899 struct wireless_dev *wdev,
17900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017901#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017902 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017903#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017904 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017905#endif
17906 int dbm)
17907{
17908 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017909 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017910 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17911 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017912 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017913
17914 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017915
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017916 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17917 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17918 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017919 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017920 if (0 != status)
17921 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017922 return status;
17923 }
17924
17925 hHal = pHddCtx->hHal;
17926
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017927 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17928 dbm, ccmCfgSetCallback,
17929 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017931 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017932 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17933 return -EIO;
17934 }
17935
17936 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17937 dbm);
17938
17939 switch(type)
17940 {
17941 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17942 /* Fall through */
17943 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17944 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17945 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17947 __func__);
17948 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017949 }
17950 break;
17951 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 __func__);
17954 return -EOPNOTSUPP;
17955 break;
17956 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17958 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017959 return -EIO;
17960 }
17961
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017962 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017963 return 0;
17964}
17965
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017966static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17967#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17968 struct wireless_dev *wdev,
17969#endif
17970#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17971 enum tx_power_setting type,
17972#else
17973 enum nl80211_tx_power_setting type,
17974#endif
17975 int dbm)
17976{
17977 int ret;
17978 vos_ssr_protect(__func__);
17979 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17980#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17981 wdev,
17982#endif
17983#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17984 type,
17985#else
17986 type,
17987#endif
17988 dbm);
17989 vos_ssr_unprotect(__func__);
17990
17991 return ret;
17992}
17993
Jeff Johnson295189b2012-06-20 16:38:30 -070017994/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017995 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017996 * This function is used to read the txpower
17997 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017998static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017999#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18000 struct wireless_dev *wdev,
18001#endif
18002 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018003{
18004
18005 hdd_adapter_t *pAdapter;
18006 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018007 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018008
Jeff Johnsone7245742012-09-05 17:12:55 -070018009 ENTER();
18010
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018011 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018012 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018013 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018014 *dbm = 0;
18015 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018016 }
18017
Jeff Johnson295189b2012-06-20 16:38:30 -070018018 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18019 if (NULL == pAdapter)
18020 {
18021 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18022 return -ENOENT;
18023 }
18024
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018025 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18026 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18027 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018028 wlan_hdd_get_classAstats(pAdapter);
18029 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18030
Jeff Johnsone7245742012-09-05 17:12:55 -070018031 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018032 return 0;
18033}
18034
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018035static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18036#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18037 struct wireless_dev *wdev,
18038#endif
18039 int *dbm)
18040{
18041 int ret;
18042
18043 vos_ssr_protect(__func__);
18044 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18045#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18046 wdev,
18047#endif
18048 dbm);
18049 vos_ssr_unprotect(__func__);
18050
18051 return ret;
18052}
18053
Dustin Brown8c1d4092017-07-28 18:08:01 +053018054/*
18055 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18056 * @stats: summary stats to use as a source
18057 * @info: kernel station_info struct to use as a destination
18058 *
18059 * Return: None
18060 */
18061static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18062 struct station_info *info)
18063{
18064 int i;
18065
18066 info->rx_packets = stats->rx_frm_cnt;
18067 info->tx_packets = 0;
18068 info->tx_retries = 0;
18069 info->tx_failed = 0;
18070
18071 for (i = 0; i < 4; ++i) {
18072 info->tx_packets += stats->tx_frm_cnt[i];
18073 info->tx_retries += stats->multiple_retry_cnt[i];
18074 info->tx_failed += stats->fail_cnt[i];
18075 }
18076
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018077#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18078 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018079 info->filled |= STATION_INFO_TX_PACKETS |
18080 STATION_INFO_TX_RETRIES |
18081 STATION_INFO_TX_FAILED |
18082 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018083#else
18084 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18085 BIT(NL80211_STA_INFO_TX_RETRIES) |
18086 BIT(NL80211_STA_INFO_TX_FAILED) |
18087 BIT(NL80211_STA_INFO_RX_PACKETS);
18088#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018089}
18090
18091/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018092 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18093 * @adapter: sap adapter pointer
18094 * @staid: station id of the client
18095 * @rssi: rssi value to fill
18096 *
18097 * Return: None
18098 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018099void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018100wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18101{
18102 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18103
18104 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18105}
18106
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018107#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18108 !defined(WITH_BACKPORTS)
18109static inline void wlan_hdd_fill_station_info_signal(struct station_info
18110 *sinfo)
18111{
18112 sinfo->filled |= STATION_INFO_SIGNAL;
18113}
18114#else
18115static inline void wlan_hdd_fill_station_info_signal(struct station_info
18116 *sinfo)
18117{
18118 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18119}
18120#endif
18121
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018122/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018123 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18124 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018125 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018126 * @info: kernel station_info struct to populate
18127 *
18128 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18129 * support "station dump" and "station get" for SAP vdevs, even though they
18130 * aren't technically stations.
18131 *
18132 * Return: errno
18133 */
18134static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018135wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18137 const u8* mac,
18138#else
18139 u8* mac,
18140#endif
18141 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018142{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018143 v_MACADDR_t *peerMacAddr;
18144 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018145 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018146 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018147
18148 status = wlan_hdd_get_station_stats(adapter);
18149 if (!VOS_IS_STATUS_SUCCESS(status)) {
18150 hddLog(VOS_TRACE_LEVEL_ERROR,
18151 "Failed to get SAP stats; status:%d", status);
18152 return 0;
18153 }
18154
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018155 peerMacAddr = (v_MACADDR_t *)mac;
18156 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18157 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18158 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18159
18160 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18161 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018162 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018163 }
18164
Dustin Brown8c1d4092017-07-28 18:08:01 +053018165 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18166
18167 return 0;
18168}
18169
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018170static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018171#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18172 const u8* mac,
18173#else
18174 u8* mac,
18175#endif
18176 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018177{
18178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18179 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18180 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053018181 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018182
18183 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18184 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018185
18186 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18187 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18188 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18189 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18190 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18191 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18192 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018193 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018194 tANI_U16 myRate;
18195 tANI_U16 currentRate = 0;
18196 tANI_U8 maxSpeedMCS = 0;
18197 tANI_U8 maxMCSIdx = 0;
18198 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018199 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018200 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018201 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018202
Leo Chang6f8870f2013-03-26 18:11:36 -070018203#ifdef WLAN_FEATURE_11AC
18204 tANI_U32 vht_mcs_map;
18205 eDataRate11ACMaxMcs vhtMaxMcs;
18206#endif /* WLAN_FEATURE_11AC */
18207
Jeff Johnsone7245742012-09-05 17:12:55 -070018208 ENTER();
18209
Dustin Brown8c1d4092017-07-28 18:08:01 +053018210 status = wlan_hdd_validate_context(pHddCtx);
18211 if (0 != status)
18212 {
18213 return status;
18214 }
18215
18216 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018217 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018218
Jeff Johnson295189b2012-06-20 16:38:30 -070018219 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
18220 (0 == ssidlen))
18221 {
18222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
18223 " Invalid ssidlen, %d", __func__, ssidlen);
18224 /*To keep GUI happy*/
18225 return 0;
18226 }
18227
Mukul Sharma811205f2014-07-09 21:07:30 +053018228 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18229 {
18230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18231 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018232 /* return a cached value */
18233 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018234 return 0;
18235 }
18236
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018237 wlan_hdd_get_station_stats(pAdapter);
18238 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018239
Kiet Lam3b17fc82013-09-27 05:24:08 +053018240 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018241 wlan_hdd_get_snr(pAdapter, &snr);
18242 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018243 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018244 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018245 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018246 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018247
c_hpothu09f19542014-05-30 21:53:31 +053018248 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018249 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18250 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018251 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018252 {
18253 rate_flags = pAdapter->maxRateFlags;
18254 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018255
Jeff Johnson295189b2012-06-20 16:38:30 -070018256 //convert to the UI units of 100kbps
18257 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18258
18259#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018260 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 -070018261 sinfo->signal,
18262 pCfg->reportMaxLinkSpeed,
18263 myRate,
18264 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018265 (int) pCfg->linkSpeedRssiMid,
18266 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018267 (int) rate_flags,
18268 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018269#endif //LINKSPEED_DEBUG_ENABLED
18270
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18272 /* assume basic BW. anything else will override this later */
18273 sinfo->txrate.bw = RATE_INFO_BW_20;
18274#endif
18275
Jeff Johnson295189b2012-06-20 16:38:30 -070018276 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18277 {
18278 // we do not want to necessarily report the current speed
18279 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18280 {
18281 // report the max possible speed
18282 rssidx = 0;
18283 }
18284 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18285 {
18286 // report the max possible speed with RSSI scaling
18287 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18288 {
18289 // report the max possible speed
18290 rssidx = 0;
18291 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018292 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018293 {
18294 // report middle speed
18295 rssidx = 1;
18296 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018297 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18298 {
18299 // report middle speed
18300 rssidx = 2;
18301 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018302 else
18303 {
18304 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018305 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018306 }
18307 }
18308 else
18309 {
18310 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18311 hddLog(VOS_TRACE_LEVEL_ERROR,
18312 "%s: Invalid value for reportMaxLinkSpeed: %u",
18313 __func__, pCfg->reportMaxLinkSpeed);
18314 rssidx = 0;
18315 }
18316
18317 maxRate = 0;
18318
18319 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018320 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18321 OperationalRates, &ORLeng))
18322 {
18323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18324 /*To keep GUI happy*/
18325 return 0;
18326 }
18327
Jeff Johnson295189b2012-06-20 16:38:30 -070018328 for (i = 0; i < ORLeng; i++)
18329 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018330 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018331 {
18332 /* Validate Rate Set */
18333 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18334 {
18335 currentRate = supported_data_rate[j].supported_rate[rssidx];
18336 break;
18337 }
18338 }
18339 /* Update MAX rate */
18340 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18341 }
18342
18343 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018344 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18345 ExtendedRates, &ERLeng))
18346 {
18347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18348 /*To keep GUI happy*/
18349 return 0;
18350 }
18351
Jeff Johnson295189b2012-06-20 16:38:30 -070018352 for (i = 0; i < ERLeng; i++)
18353 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018354 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018355 {
18356 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18357 {
18358 currentRate = supported_data_rate[j].supported_rate[rssidx];
18359 break;
18360 }
18361 }
18362 /* Update MAX rate */
18363 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18364 }
c_hpothu79aab322014-07-14 21:11:01 +053018365
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018366 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018367 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018368 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018369 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018370 {
c_hpothu79aab322014-07-14 21:11:01 +053018371 if (rate_flags & eHAL_TX_RATE_VHT80)
18372 mode = 2;
18373 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18374 mode = 1;
18375 else
18376 mode = 0;
18377
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018378 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18379 MCSRates, &MCSLeng))
18380 {
18381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18382 /*To keep GUI happy*/
18383 return 0;
18384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018385 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018386#ifdef WLAN_FEATURE_11AC
18387 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018388 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018389 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018390 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018391 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018392 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018393 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018394 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018395 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018396 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018397 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018398 maxMCSIdx = 7;
18399 }
18400 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18401 {
18402 maxMCSIdx = 8;
18403 }
18404 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18405 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018406 //VHT20 is supporting 0~8
18407 if (rate_flags & eHAL_TX_RATE_VHT20)
18408 maxMCSIdx = 8;
18409 else
18410 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018411 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018412
c_hpothu79aab322014-07-14 21:11:01 +053018413 if (0 != rssidx)/*check for scaled */
18414 {
18415 //get middle rate MCS index if rssi=1/2
18416 for (i=0; i <= maxMCSIdx; i++)
18417 {
18418 if (sinfo->signal <= rssiMcsTbl[mode][i])
18419 {
18420 maxMCSIdx = i;
18421 break;
18422 }
18423 }
18424 }
18425
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018426 if (rate_flags & eHAL_TX_RATE_VHT80)
18427 {
18428 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18429 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18430 }
18431 else if (rate_flags & eHAL_TX_RATE_VHT40)
18432 {
18433 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18434 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18435 }
18436 else if (rate_flags & eHAL_TX_RATE_VHT20)
18437 {
18438 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18439 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18440 }
18441
Leo Chang6f8870f2013-03-26 18:11:36 -070018442 maxSpeedMCS = 1;
18443 if (currentRate > maxRate)
18444 {
18445 maxRate = currentRate;
18446 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018447
Leo Chang6f8870f2013-03-26 18:11:36 -070018448 }
18449 else
18450#endif /* WLAN_FEATURE_11AC */
18451 {
18452 if (rate_flags & eHAL_TX_RATE_HT40)
18453 {
18454 rateFlag |= 1;
18455 }
18456 if (rate_flags & eHAL_TX_RATE_SGI)
18457 {
18458 rateFlag |= 2;
18459 }
18460
Girish Gowli01abcee2014-07-31 20:18:55 +053018461 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018462 if (rssidx == 1 || rssidx == 2)
18463 {
18464 //get middle rate MCS index if rssi=1/2
18465 for (i=0; i <= 7; i++)
18466 {
18467 if (sinfo->signal <= rssiMcsTbl[mode][i])
18468 {
18469 temp = i+1;
18470 break;
18471 }
18472 }
18473 }
c_hpothu79aab322014-07-14 21:11:01 +053018474
18475 for (i = 0; i < MCSLeng; i++)
18476 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018477 for (j = 0; j < temp; j++)
18478 {
18479 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18480 {
18481 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018482 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018483 break;
18484 }
18485 }
18486 if ((j < temp) && (currentRate > maxRate))
18487 {
18488 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018490 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018491 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018492 }
18493 }
18494
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018495 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18496 {
18497 maxRate = myRate;
18498 maxSpeedMCS = 1;
18499 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18500 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018501 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018502 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018503 {
18504 maxRate = myRate;
18505 if (rate_flags & eHAL_TX_RATE_LEGACY)
18506 {
18507 maxSpeedMCS = 0;
18508 }
18509 else
18510 {
18511 maxSpeedMCS = 1;
18512 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18513 }
18514 }
18515
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018516 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018517 {
18518 sinfo->txrate.legacy = maxRate;
18519#ifdef LINKSPEED_DEBUG_ENABLED
18520 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18521#endif //LINKSPEED_DEBUG_ENABLED
18522 }
18523 else
18524 {
18525 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018526#ifdef WLAN_FEATURE_11AC
18527 sinfo->txrate.nss = 1;
18528 if (rate_flags & eHAL_TX_RATE_VHT80)
18529 {
18530 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18532 defined(WITH_BACKPORTS)
18533 sinfo->txrate.bw = RATE_INFO_BW_80;
18534#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018535 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018536#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018537 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018538 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018539 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018540 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18542 defined(WITH_BACKPORTS)
18543 sinfo->txrate.bw = RATE_INFO_BW_40;
18544#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018545 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018546#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018547 }
18548 else if (rate_flags & eHAL_TX_RATE_VHT20)
18549 {
18550 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18551 }
18552#endif /* WLAN_FEATURE_11AC */
18553 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18554 {
18555 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18556 if (rate_flags & eHAL_TX_RATE_HT40)
18557 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18559 defined(WITH_BACKPORTS)
18560 sinfo->txrate.bw = RATE_INFO_BW_40;
18561#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018562 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018563#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018564 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018566 if (rate_flags & eHAL_TX_RATE_SGI)
18567 {
18568 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18569 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018570
Jeff Johnson295189b2012-06-20 16:38:30 -070018571#ifdef LINKSPEED_DEBUG_ENABLED
18572 pr_info("Reporting MCS rate %d flags %x\n",
18573 sinfo->txrate.mcs,
18574 sinfo->txrate.flags );
18575#endif //LINKSPEED_DEBUG_ENABLED
18576 }
18577 }
18578 else
18579 {
18580 // report current rate instead of max rate
18581
18582 if (rate_flags & eHAL_TX_RATE_LEGACY)
18583 {
18584 //provide to the UI in units of 100kbps
18585 sinfo->txrate.legacy = myRate;
18586#ifdef LINKSPEED_DEBUG_ENABLED
18587 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18588#endif //LINKSPEED_DEBUG_ENABLED
18589 }
18590 else
18591 {
18592 //must be MCS
18593 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018594#ifdef WLAN_FEATURE_11AC
18595 sinfo->txrate.nss = 1;
18596 if (rate_flags & eHAL_TX_RATE_VHT80)
18597 {
18598 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18599 }
18600 else
18601#endif /* WLAN_FEATURE_11AC */
18602 {
18603 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18604 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018605 if (rate_flags & eHAL_TX_RATE_SGI)
18606 {
18607 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18608 }
18609 if (rate_flags & eHAL_TX_RATE_HT40)
18610 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018611#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18612 defined(WITH_BACKPORTS)
18613 sinfo->txrate.bw = RATE_INFO_BW_40;
18614#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018615 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018617 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018618#ifdef WLAN_FEATURE_11AC
18619 else if (rate_flags & eHAL_TX_RATE_VHT80)
18620 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018621#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18622 defined(WITH_BACKPORTS)
18623 sinfo->txrate.bw = RATE_INFO_BW_80;
18624#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018625 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018626#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018627 }
18628#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018629#ifdef LINKSPEED_DEBUG_ENABLED
18630 pr_info("Reporting actual MCS rate %d flags %x\n",
18631 sinfo->txrate.mcs,
18632 sinfo->txrate.flags );
18633#endif //LINKSPEED_DEBUG_ENABLED
18634 }
18635 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018636
18637#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18638 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018639 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018640#else
18641 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018643
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018644 sinfo->tx_packets =
18645 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18646 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18647 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18648 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18649
18650 sinfo->tx_retries =
18651 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18652 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18653 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18654 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18655
18656 sinfo->tx_failed =
18657 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18658 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18659 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18660 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18661
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018662#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18663 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018664 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018665 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018666 STATION_INFO_TX_PACKETS |
18667 STATION_INFO_TX_RETRIES |
18668 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018669#else
18670 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18671 BIT(NL80211_STA_INFO_TX_PACKETS) |
18672 BIT(NL80211_STA_INFO_TX_RETRIES) |
18673 BIT(NL80211_STA_INFO_TX_FAILED);
18674#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018675
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018676 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018677
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018678 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18679 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018680 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18681 &sinfo->txrate, sizeof(sinfo->txrate));
18682
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018683 if (rate_flags & eHAL_TX_RATE_LEGACY)
18684 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18685 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18686 sinfo->rx_packets);
18687 else
18688 hddLog(LOG1,
18689 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18690 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18691 sinfo->tx_packets, sinfo->rx_packets);
18692
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018693 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18694 TRACE_CODE_HDD_CFG80211_GET_STA,
18695 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018696 EXIT();
18697 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018698}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18700static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18701 const u8* mac, struct station_info *sinfo)
18702#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018703static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18704 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018705#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018706{
18707 int ret;
18708
18709 vos_ssr_protect(__func__);
18710 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18711 vos_ssr_unprotect(__func__);
18712
18713 return ret;
18714}
18715
18716static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018717 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018718{
18719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018720 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018721 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018722 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018723
Jeff Johnsone7245742012-09-05 17:12:55 -070018724 ENTER();
18725
Jeff Johnson295189b2012-06-20 16:38:30 -070018726 if (NULL == pAdapter)
18727 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018729 return -ENODEV;
18730 }
18731
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018732 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18733 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18734 pAdapter->sessionId, timeout));
18735
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018736 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018737 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018738 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018739 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018740 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018741 }
18742
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018743 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18744 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18745 (pHddCtx->cfg_ini->fhostArpOffload) &&
18746 (eConnectionState_Associated ==
18747 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18748 {
Amar Singhald53568e2013-09-26 11:03:45 -070018749
18750 hddLog(VOS_TRACE_LEVEL_INFO,
18751 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018752 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018753 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18754 {
18755 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018756 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018757 __func__, vos_status);
18758 }
18759 }
18760
Jeff Johnson295189b2012-06-20 16:38:30 -070018761 /**The get power cmd from the supplicant gets updated by the nl only
18762 *on successful execution of the function call
18763 *we are oppositely mapped w.r.t mode in the driver
18764 **/
18765 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18766
18767 if (VOS_STATUS_E_FAILURE == vos_status)
18768 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18770 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018771 return -EINVAL;
18772 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018773 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018774 return 0;
18775}
18776
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018777static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18778 struct net_device *dev, bool mode, int timeout)
18779{
18780 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018781
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018782 vos_ssr_protect(__func__);
18783 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18784 vos_ssr_unprotect(__func__);
18785
18786 return ret;
18787}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018788
Jeff Johnson295189b2012-06-20 16:38:30 -070018789#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018790static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18791 struct net_device *netdev,
18792 u8 key_index)
18793{
18794 ENTER();
18795 return 0;
18796}
18797
Jeff Johnson295189b2012-06-20 16:38:30 -070018798static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018799 struct net_device *netdev,
18800 u8 key_index)
18801{
18802 int ret;
18803 vos_ssr_protect(__func__);
18804 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18805 vos_ssr_unprotect(__func__);
18806 return ret;
18807}
18808#endif //LINUX_VERSION_CODE
18809
18810#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18811static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18812 struct net_device *dev,
18813 struct ieee80211_txq_params *params)
18814{
18815 ENTER();
18816 return 0;
18817}
18818#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18819static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18820 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018821{
Jeff Johnsone7245742012-09-05 17:12:55 -070018822 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018823 return 0;
18824}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018825#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018826
18827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18828static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018829 struct net_device *dev,
18830 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018831{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018832 int ret;
18833
18834 vos_ssr_protect(__func__);
18835 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18836 vos_ssr_unprotect(__func__);
18837 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018838}
18839#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18840static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18841 struct ieee80211_txq_params *params)
18842{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018843 int ret;
18844
18845 vos_ssr_protect(__func__);
18846 ret = __wlan_hdd_set_txq_params(wiphy, params);
18847 vos_ssr_unprotect(__func__);
18848 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018849}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018850#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018851
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018852static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018853 struct net_device *dev,
18854 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018855{
18856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018857 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018858 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018859 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018860 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018861 v_CONTEXT_t pVosContext = NULL;
18862 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018863
Jeff Johnsone7245742012-09-05 17:12:55 -070018864 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018865
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018866 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018867 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018869 return -EINVAL;
18870 }
18871
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018872 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18873 TRACE_CODE_HDD_CFG80211_DEL_STA,
18874 pAdapter->sessionId, pAdapter->device_mode));
18875
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018876 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18877 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018878 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018879 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018880 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018881 }
18882
Jeff Johnson295189b2012-06-20 16:38:30 -070018883 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018884 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018885 )
18886 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018887 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18888 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18889 if(pSapCtx == NULL){
18890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18891 FL("psapCtx is NULL"));
18892 return -ENOENT;
18893 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018894 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18895 {
18896 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18897 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18898 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18899 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018900 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018901 {
18902 v_U16_t i;
18903 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18904 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018905 if ((pSapCtx->aStaInfo[i].isUsed) &&
18906 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018907 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018908 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018909 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018910 ETHER_ADDR_LEN);
18911
Jeff Johnson295189b2012-06-20 16:38:30 -070018912 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018913 "%s: Delete STA with MAC::"
18914 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018915 __func__,
18916 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18917 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018918 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018919 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018920 }
18921 }
18922 }
18923 else
18924 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018925
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018926 vos_status = hdd_softap_GetStaId(pAdapter,
18927 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018928 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18929 {
18930 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018931 "%s: Skip this DEL STA as this is not used::"
18932 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018933 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018934 return -ENOENT;
18935 }
18936
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018937 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018938 {
18939 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018940 "%s: Skip this DEL STA as deauth is in progress::"
18941 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018942 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018943 return -ENOENT;
18944 }
18945
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018946 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018947
Jeff Johnson295189b2012-06-20 16:38:30 -070018948 hddLog(VOS_TRACE_LEVEL_INFO,
18949 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018950 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018951 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018952 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018953
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018954 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018955 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18956 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018957 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018958 hddLog(VOS_TRACE_LEVEL_INFO,
18959 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018960 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018961 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018962 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018963 return -ENOENT;
18964 }
18965
Jeff Johnson295189b2012-06-20 16:38:30 -070018966 }
18967 }
18968
18969 EXIT();
18970
18971 return 0;
18972}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018973
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018974#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018975int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018976 struct net_device *dev,
18977 struct station_del_parameters *param)
18978#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018980int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018981 struct net_device *dev, const u8 *mac)
18982#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018983int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018984 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018985#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018986#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018987{
18988 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018989 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018990
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018991 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018992
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018993#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018994 if (NULL == param) {
18995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018996 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018997 return -EINVAL;
18998 }
18999
19000 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19001 param->subtype, &delStaParams);
19002
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019003#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019004 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019005 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019006#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019007 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19008
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019009 vos_ssr_unprotect(__func__);
19010
19011 return ret;
19012}
19013
19014static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019015 struct net_device *dev,
19016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19017 const u8 *mac,
19018#else
19019 u8 *mac,
19020#endif
19021 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019022{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019023 hdd_adapter_t *pAdapter;
19024 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019025 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019026#ifdef FEATURE_WLAN_TDLS
19027 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019028
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019029 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019030
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019031 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19032 if (NULL == pAdapter)
19033 {
19034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19035 "%s: Adapter is NULL",__func__);
19036 return -EINVAL;
19037 }
19038 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19039 status = wlan_hdd_validate_context(pHddCtx);
19040 if (0 != status)
19041 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019042 return status;
19043 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019044
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019045 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19046 TRACE_CODE_HDD_CFG80211_ADD_STA,
19047 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019048 mask = params->sta_flags_mask;
19049
19050 set = params->sta_flags_set;
19051
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019053 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19054 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019055
19056 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19057 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019058 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019059 }
19060 }
19061#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019062 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019063 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019064}
19065
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19067static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19068 struct net_device *dev, const u8 *mac,
19069 struct station_parameters *params)
19070#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019071static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19072 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019073#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019074{
19075 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019076
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019077 vos_ssr_protect(__func__);
19078 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19079 vos_ssr_unprotect(__func__);
19080
19081 return ret;
19082}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019083#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019084
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019085static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019086 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019087{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019088 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19089 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019090 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019091 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019092 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019093 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019094
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019095 ENTER();
19096
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019097 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019098 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019101 return -EINVAL;
19102 }
19103
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019104 if (!pmksa) {
19105 hddLog(LOGE, FL("pmksa is NULL"));
19106 return -EINVAL;
19107 }
19108
19109 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019110 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019111 pmksa->bssid, pmksa->pmkid);
19112 return -EINVAL;
19113 }
19114
19115 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19116 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19117
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019118 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19119 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019120 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019121 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019122 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019123 }
19124
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019125 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019126 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19127
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019128 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19129 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019130
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019131 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019132 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019133 &pmk_id, 1, FALSE);
19134
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019135 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19136 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19137 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019138
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019139 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019140 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019141}
19142
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019143static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19144 struct cfg80211_pmksa *pmksa)
19145{
19146 int ret;
19147
19148 vos_ssr_protect(__func__);
19149 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19150 vos_ssr_unprotect(__func__);
19151
19152 return ret;
19153}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019154
Wilson Yang6507c4e2013-10-01 20:11:19 -070019155
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019156static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019157 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019158{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019159 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19160 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019161 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019162 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019163
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019164 ENTER();
19165
Wilson Yang6507c4e2013-10-01 20:11:19 -070019166 /* Validate pAdapter */
19167 if (NULL == pAdapter)
19168 {
19169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19170 return -EINVAL;
19171 }
19172
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019173 if (!pmksa) {
19174 hddLog(LOGE, FL("pmksa is NULL"));
19175 return -EINVAL;
19176 }
19177
19178 if (!pmksa->bssid) {
19179 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19180 return -EINVAL;
19181 }
19182
Kiet Lam98c46a12014-10-31 15:34:57 -070019183 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19184 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19185
Wilson Yang6507c4e2013-10-01 20:11:19 -070019186 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19187 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019188 if (0 != status)
19189 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019190 return status;
19191 }
19192
19193 /*Retrieve halHandle*/
19194 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19195
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019196 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19197 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19198 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019199 /* Delete the PMKID CSR cache */
19200 if (eHAL_STATUS_SUCCESS !=
19201 sme_RoamDelPMKIDfromCache(halHandle,
19202 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19203 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19204 MAC_ADDR_ARRAY(pmksa->bssid));
19205 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019206 }
19207
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019208 EXIT();
19209 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019210}
19211
Wilson Yang6507c4e2013-10-01 20:11:19 -070019212
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019213static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19214 struct cfg80211_pmksa *pmksa)
19215{
19216 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019217
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019218 vos_ssr_protect(__func__);
19219 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19220 vos_ssr_unprotect(__func__);
19221
19222 return ret;
19223
19224}
19225
19226static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019227{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19229 tHalHandle halHandle;
19230 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019231 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019232
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019233 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019234
19235 /* Validate pAdapter */
19236 if (NULL == pAdapter)
19237 {
19238 hddLog(VOS_TRACE_LEVEL_ERROR,
19239 "%s: Invalid Adapter" ,__func__);
19240 return -EINVAL;
19241 }
19242
19243 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19244 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019245 if (0 != status)
19246 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019247 return status;
19248 }
19249
19250 /*Retrieve halHandle*/
19251 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19252
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019253 /* Flush the PMKID cache in CSR */
19254 if (eHAL_STATUS_SUCCESS !=
19255 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19257 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019258 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019259 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019260 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019261}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019262
19263static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19264{
19265 int ret;
19266
19267 vos_ssr_protect(__func__);
19268 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19269 vos_ssr_unprotect(__func__);
19270
19271 return ret;
19272}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019273#endif
19274
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019275#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019276static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19277 struct net_device *dev,
19278 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019279{
19280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19281 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019282 hdd_context_t *pHddCtx;
19283 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019284
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019285 ENTER();
19286
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019287 if (NULL == pAdapter)
19288 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019290 return -ENODEV;
19291 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019292 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19293 ret = wlan_hdd_validate_context(pHddCtx);
19294 if (0 != ret)
19295 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019296 return ret;
19297 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019298 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019299 if (NULL == pHddStaCtx)
19300 {
19301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19302 return -EINVAL;
19303 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019304
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019305 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19306 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19307 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019308 // Added for debug on reception of Re-assoc Req.
19309 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19310 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019311 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019312 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019313 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019314 }
19315
19316#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019317 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019318 ftie->ie_len);
19319#endif
19320
19321 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019322 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19323 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019324 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019325
19326 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019327 return 0;
19328}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019329
19330static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19331 struct net_device *dev,
19332 struct cfg80211_update_ft_ies_params *ftie)
19333{
19334 int ret;
19335
19336 vos_ssr_protect(__func__);
19337 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19338 vos_ssr_unprotect(__func__);
19339
19340 return ret;
19341}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019342#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019343
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019344#ifdef FEATURE_WLAN_SCAN_PNO
19345
19346void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19347 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19348{
19349 int ret;
19350 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19351 hdd_context_t *pHddCtx;
19352
Nirav Shah80830bf2013-12-31 16:35:12 +053019353 ENTER();
19354
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019355 if (NULL == pAdapter)
19356 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019358 "%s: HDD adapter is Null", __func__);
19359 return ;
19360 }
19361
19362 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19363 if (NULL == pHddCtx)
19364 {
19365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19366 "%s: HDD context is Null!!!", __func__);
19367 return ;
19368 }
19369
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019370 spin_lock(&pHddCtx->schedScan_lock);
19371 if (TRUE == pHddCtx->isWiphySuspended)
19372 {
19373 pHddCtx->isSchedScanUpdatePending = TRUE;
19374 spin_unlock(&pHddCtx->schedScan_lock);
19375 hddLog(VOS_TRACE_LEVEL_INFO,
19376 "%s: Update cfg80211 scan database after it resume", __func__);
19377 return ;
19378 }
19379 spin_unlock(&pHddCtx->schedScan_lock);
19380
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019381 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19382
19383 if (0 > ret)
19384 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019385 else
19386 {
19387 /* Acquire wakelock to handle the case where APP's tries to suspend
19388 * immediatly after the driver gets connect request(i.e after pno)
19389 * from supplicant, this result in app's is suspending and not able
19390 * to process the connect request to AP */
19391 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19392 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019393 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19395 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019396}
19397
19398/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019399 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019400 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019401 */
19402static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19403{
19404 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19405 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019406 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019407 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19408 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019409
19410 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19411 {
19412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19413 "%s: PNO is allowed only in STA interface", __func__);
19414 return eHAL_STATUS_FAILURE;
19415 }
19416
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019417 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19418
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019419 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019420 * active sessions. PNO is allowed only in case when sap session
19421 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019422 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019423 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19424 {
19425 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019426 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019427
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019428 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19429 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19430 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19431 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019432 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19433 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019434 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019435 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019436 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019437 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019438 }
19439 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19440 pAdapterNode = pNext;
19441 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019442 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019443}
19444
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019445void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19446{
19447 hdd_adapter_t *pAdapter = callbackContext;
19448 hdd_context_t *pHddCtx;
19449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019450 ENTER();
19451
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019452 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19453 {
19454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19455 FL("Invalid adapter or adapter has invalid magic"));
19456 return;
19457 }
19458
19459 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19460 if (0 != wlan_hdd_validate_context(pHddCtx))
19461 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019462 return;
19463 }
19464
c_hpothub53c45d2014-08-18 16:53:14 +053019465 if (VOS_STATUS_SUCCESS != status)
19466 {
19467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019468 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019469 pHddCtx->isPnoEnable = FALSE;
19470 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019471
19472 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19473 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019474 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019475}
19476
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19478 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19479/**
19480 * hdd_config_sched_scan_plan() - configures the sched scan plans
19481 * from the framework.
19482 * @pno_req: pointer to PNO scan request
19483 * @request: pointer to scan request from framework
19484 *
19485 * Return: None
19486 */
19487static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19488 struct cfg80211_sched_scan_request *request,
19489 hdd_context_t *hdd_ctx)
19490{
19491 v_U32_t i = 0;
19492
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019493 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019494 for (i = 0; i < request->n_scan_plans; i++)
19495 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019496 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19497 request->scan_plans[i].iterations;
19498 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19499 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019500 }
19501}
19502#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019503static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019504 struct cfg80211_sched_scan_request *request,
19505 hdd_context_t *hdd_ctx)
19506{
19507 v_U32_t i, temp_int;
19508 /* Driver gets only one time interval which is hardcoded in
19509 * supplicant for 10000ms. Taking power consumption into account 6
19510 * timers will be used, Timervalue is increased exponentially
19511 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19512 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19513 * If it is set to 0 only one timer will be used and PNO scan cycle
19514 * will be repeated after each interval specified by supplicant
19515 * till PNO is disabled.
19516 */
19517 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019518 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019519 HDD_PNO_SCAN_TIMERS_SET_ONE;
19520 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019521 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019522 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19523
19524 temp_int = (request->interval)/1000;
19525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19526 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19527 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019528 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019529 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019530 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019531 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019532 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019533 temp_int *= 2;
19534 }
19535 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019536 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019537}
19538#endif
19539
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019540/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019541 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19542 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019543 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019544static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019545 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19546{
19547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019548 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019549 hdd_context_t *pHddCtx;
19550 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019551 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019552 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19553 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019554 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19555 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019556 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019557 hdd_config_t *pConfig = NULL;
19558 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019560 ENTER();
19561
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019562 if (NULL == pAdapter)
19563 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019565 "%s: HDD adapter is Null", __func__);
19566 return -ENODEV;
19567 }
19568
19569 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019570 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019571
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019572 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019573 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019574 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019575 }
19576
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019577 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019578 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19579 if (NULL == hHal)
19580 {
19581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19582 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019583 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019584 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019585 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19586 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19587 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019588 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019589 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019590 {
19591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19592 "%s: aborting the existing scan is unsuccessfull", __func__);
19593 return -EBUSY;
19594 }
19595
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019596 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019597 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019599 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019600 return -EBUSY;
19601 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019602
c_hpothu37f21312014-04-09 21:49:54 +053019603 if (TRUE == pHddCtx->isPnoEnable)
19604 {
19605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19606 FL("already PNO is enabled"));
19607 return -EBUSY;
19608 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019609
19610 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19611 {
19612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19613 "%s: abort ROC failed ", __func__);
19614 return -EBUSY;
19615 }
19616
c_hpothu37f21312014-04-09 21:49:54 +053019617 pHddCtx->isPnoEnable = TRUE;
19618
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019619 pnoRequest.enable = 1; /*Enable PNO */
19620 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019621
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019622 if (( !pnoRequest.ucNetworksCount ) ||
19623 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019624 {
19625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019626 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019627 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019628 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019629 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019630 goto error;
19631 }
19632
19633 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19634 {
19635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019636 "%s: Incorrect number of channels %d",
19637 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019638 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019639 goto error;
19640 }
19641
19642 /* Framework provides one set of channels(all)
19643 * common for all saved profile */
19644 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19645 channels_allowed, &num_channels_allowed))
19646 {
19647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19648 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019649 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019650 goto error;
19651 }
19652 /* Checking each channel against allowed channel list */
19653 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019654 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019655 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019656 char chList [(request->n_channels*5)+1];
19657 int len;
19658 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019659 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019660 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019661 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019662 if (request->channels[i]->hw_value == channels_allowed[indx])
19663 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019664 if ((!pConfig->enableDFSPnoChnlScan) &&
19665 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19666 {
19667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19668 "%s : Dropping DFS channel : %d",
19669 __func__,channels_allowed[indx]);
19670 num_ignore_dfs_ch++;
19671 break;
19672 }
19673
Nirav Shah80830bf2013-12-31 16:35:12 +053019674 valid_ch[num_ch++] = request->channels[i]->hw_value;
19675 len += snprintf(chList+len, 5, "%d ",
19676 request->channels[i]->hw_value);
19677 break ;
19678 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019679 }
19680 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019681 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019682
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019683 /*If all channels are DFS and dropped, then ignore the PNO request*/
19684 if (num_ignore_dfs_ch == request->n_channels)
19685 {
19686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19687 "%s : All requested channels are DFS channels", __func__);
19688 ret = -EINVAL;
19689 goto error;
19690 }
19691 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019692
19693 pnoRequest.aNetworks =
19694 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19695 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019696 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019697 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19698 FL("failed to allocate memory aNetworks %u"),
19699 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19700 goto error;
19701 }
19702 vos_mem_zero(pnoRequest.aNetworks,
19703 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19704
19705 /* Filling per profile params */
19706 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19707 {
19708 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019709 request->match_sets[i].ssid.ssid_len;
19710
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019711 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19712 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019713 {
19714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019715 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019716 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019717 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019718 goto error;
19719 }
19720
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019721 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019722 request->match_sets[i].ssid.ssid,
19723 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19725 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019726 i, pnoRequest.aNetworks[i].ssId.ssId);
19727 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19728 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19729 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019730
19731 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019732 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19733 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019734
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019735 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019736 }
19737
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019738 for (i = 0; i < request->n_ssids; i++)
19739 {
19740 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019741 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019742 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019743 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019744 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019745 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019746 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019747 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019748 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019749 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019750 break;
19751 }
19752 j++;
19753 }
19754 }
19755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19756 "Number of hidden networks being Configured = %d",
19757 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019759 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019760
19761 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19762 if (pnoRequest.p24GProbeTemplate == NULL)
19763 {
19764 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19765 FL("failed to allocate memory p24GProbeTemplate %u"),
19766 SIR_PNO_MAX_PB_REQ_SIZE);
19767 goto error;
19768 }
19769
19770 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19771 if (pnoRequest.p5GProbeTemplate == NULL)
19772 {
19773 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19774 FL("failed to allocate memory p5GProbeTemplate %u"),
19775 SIR_PNO_MAX_PB_REQ_SIZE);
19776 goto error;
19777 }
19778
19779 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19780 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19781
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019782 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19783 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019784 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019785 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19786 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19787 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019788
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019789 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19790 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19791 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019792 }
19793
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019794 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019795
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019796 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019797
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019798 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019799 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19800 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019801 pAdapter->pno_req_status = 0;
19802
Nirav Shah80830bf2013-12-31 16:35:12 +053019803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19804 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019805 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19806 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019807
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019808 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019809 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019810 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19811 if (eHAL_STATUS_SUCCESS != status)
19812 {
19813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019814 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019815 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019816 goto error;
19817 }
19818
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019819 ret = wait_for_completion_timeout(
19820 &pAdapter->pno_comp_var,
19821 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19822 if (0 >= ret)
19823 {
19824 // Did not receive the response for PNO enable in time.
19825 // Assuming the PNO enable was success.
19826 // Returning error from here, because we timeout, results
19827 // in side effect of Wifi (Wifi Setting) not to work.
19828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19829 FL("Timed out waiting for PNO to be Enabled"));
19830 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019831 }
19832
19833 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019834 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019835
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019836error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19838 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019839 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019840 if (pnoRequest.aNetworks)
19841 vos_mem_free(pnoRequest.aNetworks);
19842 if (pnoRequest.p24GProbeTemplate)
19843 vos_mem_free(pnoRequest.p24GProbeTemplate);
19844 if (pnoRequest.p5GProbeTemplate)
19845 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019846
19847 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019848 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019849}
19850
19851/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019852 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19853 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019854 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019855static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19856 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19857{
19858 int ret;
19859
19860 vos_ssr_protect(__func__);
19861 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19862 vos_ssr_unprotect(__func__);
19863
19864 return ret;
19865}
19866
19867/*
19868 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19869 * Function to disable PNO
19870 */
19871static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019872 struct net_device *dev)
19873{
19874 eHalStatus status = eHAL_STATUS_FAILURE;
19875 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19876 hdd_context_t *pHddCtx;
19877 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019878 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019879 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019880
19881 ENTER();
19882
19883 if (NULL == pAdapter)
19884 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019886 "%s: HDD adapter is Null", __func__);
19887 return -ENODEV;
19888 }
19889
19890 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019891
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019892 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019893 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019895 "%s: HDD context is Null", __func__);
19896 return -ENODEV;
19897 }
19898
19899 /* The return 0 is intentional when isLogpInProgress and
19900 * isLoadUnloadInProgress. We did observe a crash due to a return of
19901 * failure in sched_scan_stop , especially for a case where the unload
19902 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19903 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19904 * success. If it returns a failure , then its next invocation due to the
19905 * clean up of the second interface will have the dev pointer corresponding
19906 * to the first one leading to a crash.
19907 */
19908 if (pHddCtx->isLogpInProgress)
19909 {
19910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19911 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019912 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019913 return ret;
19914 }
19915
Mihir Shete18156292014-03-11 15:38:30 +053019916 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019917 {
19918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19919 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19920 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019921 }
19922
19923 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19924 if (NULL == hHal)
19925 {
19926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19927 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019928 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019929 }
19930
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019931 pnoRequest.enable = 0; /* Disable PNO */
19932 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019933
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019934 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19935 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19936 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019937
19938 INIT_COMPLETION(pAdapter->pno_comp_var);
19939 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19940 pnoRequest.callbackContext = pAdapter;
19941 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019942 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019943 pAdapter->sessionId,
19944 NULL, pAdapter);
19945 if (eHAL_STATUS_SUCCESS != status)
19946 {
19947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19948 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019949 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019950 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019951 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019952 ret = wait_for_completion_timeout(
19953 &pAdapter->pno_comp_var,
19954 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19955 if (0 >= ret)
19956 {
19957 // Did not receive the response for PNO disable in time.
19958 // Assuming the PNO disable was success.
19959 // Returning error from here, because we timeout, results
19960 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019962 FL("Timed out waiting for PNO to be disabled"));
19963 ret = 0;
19964 }
19965
19966 ret = pAdapter->pno_req_status;
19967 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019968
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019969error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019971 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019972
19973 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019974 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019975}
19976
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019977/*
19978 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19979 * NL interface to disable PNO
19980 */
19981static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19982 struct net_device *dev)
19983{
19984 int ret;
19985
19986 vos_ssr_protect(__func__);
19987 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19988 vos_ssr_unprotect(__func__);
19989
19990 return ret;
19991}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019992#endif /*FEATURE_WLAN_SCAN_PNO*/
19993
19994
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019995#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019996#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019997static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19998 struct net_device *dev,
19999 u8 *peer, u8 action_code,
20000 u8 dialog_token,
20001 u16 status_code, u32 peer_capability,
20002 const u8 *buf, size_t len)
20003#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020004#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20005 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020006static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20007 struct net_device *dev,
20008 const u8 *peer, u8 action_code,
20009 u8 dialog_token, u16 status_code,
20010 u32 peer_capability, bool initiator,
20011 const u8 *buf, size_t len)
20012#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20013static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20014 struct net_device *dev,
20015 const u8 *peer, u8 action_code,
20016 u8 dialog_token, u16 status_code,
20017 u32 peer_capability, const u8 *buf,
20018 size_t len)
20019#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20020static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20021 struct net_device *dev,
20022 u8 *peer, u8 action_code,
20023 u8 dialog_token,
20024 u16 status_code, u32 peer_capability,
20025 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020026#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020027static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20028 struct net_device *dev,
20029 u8 *peer, u8 action_code,
20030 u8 dialog_token,
20031 u16 status_code, const u8 *buf,
20032 size_t len)
20033#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020034#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020035{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020036 hdd_adapter_t *pAdapter;
20037 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020038 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020039 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020040 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020041 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020042 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020043 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020044#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020045 u32 peer_capability = 0;
20046#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020047 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020048 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020049 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020050
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020051 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20052 if (NULL == pAdapter)
20053 {
20054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20055 "%s: Adapter is NULL",__func__);
20056 return -EINVAL;
20057 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020058 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20059 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20060 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020061
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020062 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020063 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020066 "Invalid arguments");
20067 return -EINVAL;
20068 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020069
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020070 if (pHddCtx->isLogpInProgress)
20071 {
20072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20073 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020074 wlan_hdd_tdls_set_link_status(pAdapter,
20075 peer,
20076 eTDLS_LINK_IDLE,
20077 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020078 return -EBUSY;
20079 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020080
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020081 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20082 {
20083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20084 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20085 return -EAGAIN;
20086 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020087
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020088 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20089 if (!pHddTdlsCtx) {
20090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20091 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020092 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020093 }
20094
Hoonki Lee27511902013-03-14 18:19:06 -070020095 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020096 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020098 "%s: TDLS mode is disabled OR not enabled in FW."
20099 MAC_ADDRESS_STR " action %d declined.",
20100 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020101 return -ENOTSUPP;
20102 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020103
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020104 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20105
20106 if( NULL == pHddStaCtx )
20107 {
20108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20109 "%s: HDD station context NULL ",__func__);
20110 return -EINVAL;
20111 }
20112
20113 /* STA should be connected and authenticated
20114 * before sending any TDLS frames
20115 */
20116 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20117 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20118 {
20119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20120 "STA is not connected or unauthenticated. "
20121 "connState %u, uIsAuthenticated %u",
20122 pHddStaCtx->conn_info.connState,
20123 pHddStaCtx->conn_info.uIsAuthenticated);
20124 return -EAGAIN;
20125 }
20126
Hoonki Lee27511902013-03-14 18:19:06 -070020127 /* other than teardown frame, other mgmt frames are not sent if disabled */
20128 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20129 {
20130 /* if tdls_mode is disabled to respond to peer's request */
20131 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20132 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020134 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020135 " TDLS mode is disabled. action %d declined.",
20136 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020137
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020138 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020139 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020140
20141 if (vos_max_concurrent_connections_reached())
20142 {
20143 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20144 return -EINVAL;
20145 }
Hoonki Lee27511902013-03-14 18:19:06 -070020146 }
20147
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020148 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20149 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020150 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020151 {
20152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020153 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020154 " TDLS setup is ongoing. action %d declined.",
20155 __func__, MAC_ADDR_ARRAY(peer), action_code);
20156 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020157 }
20158 }
20159
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020160 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20161 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020162 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020163 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20164 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020165 {
20166 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20167 we return error code at 'add_station()'. Hence we have this
20168 check again in addtion to add_station().
20169 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020170 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020171 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20173 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020174 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20175 __func__, MAC_ADDR_ARRAY(peer), action_code,
20176 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020177 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020178 }
20179 else
20180 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020181 /* maximum reached. tweak to send error code to peer and return
20182 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020183 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20185 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020186 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20187 __func__, MAC_ADDR_ARRAY(peer), status_code,
20188 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020189 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020190 /* fall through to send setup resp with failure status
20191 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020192 }
20193 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020194 else
20195 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020196 mutex_lock(&pHddCtx->tdls_lock);
20197 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020198 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020199 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020200 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020202 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20203 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020204 return -EPERM;
20205 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020206 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020207 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020208 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020209
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020211 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020212 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20213 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020214
Hoonki Leea34dd892013-02-05 22:56:02 -080020215 /*Except teardown responder will not be used so just make 0*/
20216 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020217 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020218 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020219
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020220 mutex_lock(&pHddCtx->tdls_lock);
20221 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020222
20223 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20224 responder = pTdlsPeer->is_responder;
20225 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020226 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020228 "%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 -070020229 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20230 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020231 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020232 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020233 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020234 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020235 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020236
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020237 /* Discard TDLS setup if peer is removed by user app */
20238 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20239 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20240 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20241 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20242
20243 mutex_lock(&pHddCtx->tdls_lock);
20244 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20245 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20246 mutex_unlock(&pHddCtx->tdls_lock);
20247 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20248 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20249 MAC_ADDR_ARRAY(peer), action_code);
20250 return -EINVAL;
20251 }
20252 mutex_unlock(&pHddCtx->tdls_lock);
20253 }
20254
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020255 /* For explicit trigger of DIS_REQ come out of BMPS for
20256 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020257 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020258 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020259 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20260 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020261 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020262 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020264 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20265 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020266 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20267 if (status != VOS_STATUS_SUCCESS) {
20268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020269 } else {
20270 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020271 }
Hoonki Lee14621352013-04-16 17:51:19 -070020272 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020273 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020274 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020275 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20276 }
20277 }
Hoonki Lee14621352013-04-16 17:51:19 -070020278 }
20279
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020280 /* make sure doesn't call send_mgmt() while it is pending */
20281 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20282 {
20283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020284 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020285 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020286 ret = -EBUSY;
20287 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020288 }
20289
20290 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020291 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20292
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020293 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20294 pAdapter->sessionId, peer, action_code, dialog_token,
20295 status_code, peer_capability, (tANI_U8 *)buf, len,
20296 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020297
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020298 if (VOS_STATUS_SUCCESS != status)
20299 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20301 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020302 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020303 ret = -EINVAL;
20304 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020305 }
20306
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20308 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20309 WAIT_TIME_TDLS_MGMT);
20310
Hoonki Leed37cbb32013-04-20 00:31:14 -070020311 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20312 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20313
20314 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020315 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020317 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020318 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020319 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020320
20321 if (pHddCtx->isLogpInProgress)
20322 {
20323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20324 "%s: LOGP in Progress. Ignore!!!", __func__);
20325 return -EAGAIN;
20326 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020327 if (rc <= 0)
20328 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20329 WLAN_LOG_INDICATOR_HOST_DRIVER,
20330 WLAN_LOG_REASON_HDD_TIME_OUT,
20331 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020332
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020333 ret = -EINVAL;
20334 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020335 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020336 else
20337 {
20338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20339 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20340 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20341 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020342
Gopichand Nakkala05922802013-03-14 12:23:19 -070020343 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020344 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020345 ret = max_sta_failed;
20346 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020347 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020348
Hoonki Leea34dd892013-02-05 22:56:02 -080020349 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20350 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020351 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020352 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20353 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020354 }
20355 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20356 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020357 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20359 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020360 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020361
20362 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020363
20364tx_failed:
20365 /* add_station will be called before sending TDLS_SETUP_REQ and
20366 * TDLS_SETUP_RSP and as part of add_station driver will enable
20367 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20368 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20369 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20370 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20371 */
20372
20373 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20374 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20375 wlan_hdd_tdls_check_bmps(pAdapter);
20376 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020377}
20378
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020379#if TDLS_MGMT_VERSION2
20380static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20381 u8 *peer, u8 action_code, u8 dialog_token,
20382 u16 status_code, u32 peer_capability,
20383 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020384#else /* TDLS_MGMT_VERSION2 */
20385#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20386static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20387 struct net_device *dev,
20388 const u8 *peer, u8 action_code,
20389 u8 dialog_token, u16 status_code,
20390 u32 peer_capability, bool initiator,
20391 const u8 *buf, size_t len)
20392#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20393static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20394 struct net_device *dev,
20395 const u8 *peer, u8 action_code,
20396 u8 dialog_token, u16 status_code,
20397 u32 peer_capability, const u8 *buf,
20398 size_t len)
20399#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20400static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20401 struct net_device *dev,
20402 u8 *peer, u8 action_code,
20403 u8 dialog_token,
20404 u16 status_code, u32 peer_capability,
20405 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020406#else
20407static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20408 u8 *peer, u8 action_code, u8 dialog_token,
20409 u16 status_code, const u8 *buf, size_t len)
20410#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020411#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020412{
20413 int ret;
20414
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020415 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020416#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020417 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20418 dialog_token, status_code,
20419 peer_capability, buf, len);
20420#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20422 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020423 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20424 dialog_token, status_code,
20425 peer_capability, initiator,
20426 buf, len);
20427#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20428 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20429 dialog_token, status_code,
20430 peer_capability, buf, len);
20431#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20432 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20433 dialog_token, status_code,
20434 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020435#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020436 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20437 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020438#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020439#endif
20440 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020441
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020442 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020443}
Atul Mittal115287b2014-07-08 13:26:33 +053020444
20445int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020446#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20447 const u8 *peer,
20448#else
Atul Mittal115287b2014-07-08 13:26:33 +053020449 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020450#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020451 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020452 cfg80211_exttdls_callback callback)
20453{
20454
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020455 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020456 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020457 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20459 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20460 __func__, MAC_ADDR_ARRAY(peer));
20461
20462 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20463 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20464
20465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020466 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20467 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20468 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020469 return -ENOTSUPP;
20470 }
20471
20472 /* To cater the requirement of establishing the TDLS link
20473 * irrespective of the data traffic , get an entry of TDLS peer.
20474 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020475 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020476 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20477 if (pTdlsPeer == NULL) {
20478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20479 "%s: peer " MAC_ADDRESS_STR " not existing",
20480 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020481 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020482 return -EINVAL;
20483 }
20484
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020485 /* check FW TDLS Off Channel capability */
20486 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020487 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020488 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020489 {
20490 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20491 pTdlsPeer->peerParams.global_operating_class =
20492 tdls_peer_params->global_operating_class;
20493 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20494 pTdlsPeer->peerParams.min_bandwidth_kbps =
20495 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020496 /* check configured channel is valid, non dfs and
20497 * not current operating channel */
20498 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20499 tdls_peer_params->channel)) &&
20500 (pHddStaCtx) &&
20501 (tdls_peer_params->channel !=
20502 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020503 {
20504 pTdlsPeer->isOffChannelConfigured = TRUE;
20505 }
20506 else
20507 {
20508 pTdlsPeer->isOffChannelConfigured = FALSE;
20509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20510 "%s: Configured Tdls Off Channel is not valid", __func__);
20511
20512 }
20513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020514 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20515 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020516 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020517 pTdlsPeer->isOffChannelConfigured,
20518 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020519 }
20520 else
20521 {
20522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020523 "%s: TDLS off channel FW capability %d, "
20524 "host capab %d or Invalid TDLS Peer Params", __func__,
20525 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20526 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020527 }
20528
Atul Mittal115287b2014-07-08 13:26:33 +053020529 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20530
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020531 mutex_unlock(&pHddCtx->tdls_lock);
20532
Atul Mittal115287b2014-07-08 13:26:33 +053020533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20534 " %s TDLS Add Force Peer Failed",
20535 __func__);
20536 return -EINVAL;
20537 }
20538 /*EXT TDLS*/
20539
20540 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020541 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20543 " %s TDLS set callback Failed",
20544 __func__);
20545 return -EINVAL;
20546 }
20547
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020548 mutex_unlock(&pHddCtx->tdls_lock);
20549
Atul Mittal115287b2014-07-08 13:26:33 +053020550 return(0);
20551
20552}
20553
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020554int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20556 const u8 *peer
20557#else
20558 u8 *peer
20559#endif
20560)
Atul Mittal115287b2014-07-08 13:26:33 +053020561{
20562
20563 hddTdlsPeer_t *pTdlsPeer;
20564 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020565
Atul Mittal115287b2014-07-08 13:26:33 +053020566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20567 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20568 __func__, MAC_ADDR_ARRAY(peer));
20569
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020570 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20572 return -EINVAL;
20573 }
20574
Atul Mittal115287b2014-07-08 13:26:33 +053020575 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20576 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20577
20578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020579 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20580 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20581 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020582 return -ENOTSUPP;
20583 }
20584
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020585 mutex_lock(&pHddCtx->tdls_lock);
20586 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020587
20588 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020589 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020590 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020591 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020592 __func__, MAC_ADDR_ARRAY(peer));
20593 return -EINVAL;
20594 }
20595 else {
20596 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20597 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020598 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20599 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020600 /* if channel switch is configured, reset
20601 the channel for this peer */
20602 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20603 {
20604 pTdlsPeer->peerParams.channel = 0;
20605 pTdlsPeer->isOffChannelConfigured = FALSE;
20606 }
Atul Mittal115287b2014-07-08 13:26:33 +053020607 }
20608
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020609 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020610 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020612 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020613 }
Atul Mittal115287b2014-07-08 13:26:33 +053020614
20615 /*EXT TDLS*/
20616
20617 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020618 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20620 " %s TDLS set callback Failed",
20621 __func__);
20622 return -EINVAL;
20623 }
Atul Mittal115287b2014-07-08 13:26:33 +053020624
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020625 mutex_unlock(&pHddCtx->tdls_lock);
20626
20627 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020628}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020629static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20631 const u8 *peer,
20632#else
20633 u8 *peer,
20634#endif
20635 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020636{
20637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20638 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020639 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020640 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020642 ENTER();
20643
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020644 if (!pAdapter) {
20645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20646 return -EINVAL;
20647 }
20648
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020649 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20650 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20651 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020652 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020653 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020655 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020656 return -EINVAL;
20657 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020658
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020660 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020662 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020663 }
20664
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020665
20666 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020667 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020668 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020670 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20671 "Cannot process TDLS commands",
20672 pHddCtx->cfg_ini->fEnableTDLSSupport,
20673 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020674 return -ENOTSUPP;
20675 }
20676
20677 switch (oper) {
20678 case NL80211_TDLS_ENABLE_LINK:
20679 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020680 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020681 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020682 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20683 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020684 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020685 tANI_U16 numCurrTdlsPeers = 0;
20686 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020687 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020688 tSirMacAddr peerMac;
20689 int channel;
20690 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020691
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20693 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20694 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020695
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020696 mutex_lock(&pHddCtx->tdls_lock);
20697 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020698 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020699 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020700 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020701 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20702 " (oper %d) not exsting. ignored",
20703 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20704 return -EINVAL;
20705 }
20706
20707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20708 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20709 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20710 "NL80211_TDLS_ENABLE_LINK");
20711
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020712 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20713 {
20714 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20715 MAC_ADDRESS_STR " failed",
20716 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020717 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020718 return -EINVAL;
20719 }
20720
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020721 /* before starting tdls connection, set tdls
20722 * off channel established status to default value */
20723 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020724
20725 mutex_unlock(&pHddCtx->tdls_lock);
20726
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020727 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020728 /* TDLS Off Channel, Disable tdls channel switch,
20729 when there are more than one tdls link */
20730 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020731 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020732 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020733 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020734 /* get connected peer and send disable tdls off chan */
20735 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020736 if ((connPeer) &&
20737 (connPeer->isOffChannelSupported == TRUE) &&
20738 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020739 {
20740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20741 "%s: More then one peer connected, Disable "
20742 "TDLS channel switch", __func__);
20743
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020744 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020745 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20746 channel = connPeer->peerParams.channel;
20747
20748 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020749
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020750 ret = sme_SendTdlsChanSwitchReq(
20751 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020752 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020753 peerMac,
20754 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020755 TDLS_OFF_CHANNEL_BW_OFFSET,
20756 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020757 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020758 hddLog(VOS_TRACE_LEVEL_ERROR,
20759 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020760 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020761 }
20762 else
20763 {
20764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20765 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020766 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020767 "isOffChannelConfigured %d",
20768 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020769 (connPeer ? (connPeer->isOffChannelSupported)
20770 : -1),
20771 (connPeer ? (connPeer->isOffChannelConfigured)
20772 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020773 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020774 }
20775 }
20776
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020777 mutex_lock(&pHddCtx->tdls_lock);
20778 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20779 if ( NULL == pTdlsPeer ) {
20780 mutex_unlock(&pHddCtx->tdls_lock);
20781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20782 "%s: " MAC_ADDRESS_STR
20783 " (oper %d) peer got freed in other context. ignored",
20784 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20785 return -EINVAL;
20786 }
20787 peer_status = pTdlsPeer->link_status;
20788 mutex_unlock(&pHddCtx->tdls_lock);
20789
20790 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020791 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020792 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020793
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020794 if (0 != wlan_hdd_tdls_get_link_establish_params(
20795 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020796 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020797 return -EINVAL;
20798 }
20799 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020800
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020801 ret = sme_SendTdlsLinkEstablishParams(
20802 WLAN_HDD_GET_HAL_CTX(pAdapter),
20803 pAdapter->sessionId, peer,
20804 &tdlsLinkEstablishParams);
20805 if (ret != VOS_STATUS_SUCCESS) {
20806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20807 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020808 /* Send TDLS peer UAPSD capabilities to the firmware and
20809 * register with the TL on after the response for this operation
20810 * is received .
20811 */
20812 ret = wait_for_completion_interruptible_timeout(
20813 &pAdapter->tdls_link_establish_req_comp,
20814 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020815
20816 mutex_lock(&pHddCtx->tdls_lock);
20817 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20818 if ( NULL == pTdlsPeer ) {
20819 mutex_unlock(&pHddCtx->tdls_lock);
20820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20821 "%s %d: " MAC_ADDRESS_STR
20822 " (oper %d) peer got freed in other context. ignored",
20823 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20824 (int)oper);
20825 return -EINVAL;
20826 }
20827 peer_status = pTdlsPeer->link_status;
20828 mutex_unlock(&pHddCtx->tdls_lock);
20829
20830 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020831 {
20832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020833 FL("Link Establish Request Failed Status %ld"),
20834 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020835 return -EINVAL;
20836 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020837 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020838
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020839 mutex_lock(&pHddCtx->tdls_lock);
20840 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20841 if ( NULL == pTdlsPeer ) {
20842 mutex_unlock(&pHddCtx->tdls_lock);
20843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20844 "%s: " MAC_ADDRESS_STR
20845 " (oper %d) peer got freed in other context. ignored",
20846 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20847 return -EINVAL;
20848 }
20849
Atul Mittal115287b2014-07-08 13:26:33 +053020850 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20851 eTDLS_LINK_CONNECTED,
20852 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020853 staDesc.ucSTAId = pTdlsPeer->staId;
20854 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020855
20856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20857 "%s: tdlsLinkEstablishParams of peer "
20858 MAC_ADDRESS_STR "uapsdQueues: %d"
20859 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20860 "isResponder: %d peerstaId: %d",
20861 __func__,
20862 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20863 tdlsLinkEstablishParams.uapsdQueues,
20864 tdlsLinkEstablishParams.qos,
20865 tdlsLinkEstablishParams.maxSp,
20866 tdlsLinkEstablishParams.isBufSta,
20867 tdlsLinkEstablishParams.isOffChannelSupported,
20868 tdlsLinkEstablishParams.isResponder,
20869 pTdlsPeer->staId);
20870
20871 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20872 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20873 __func__,
20874 staDesc.ucSTAId,
20875 staDesc.ucQosEnabled);
20876
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020877 ret = WLANTL_UpdateTdlsSTAClient(
20878 pHddCtx->pvosContext,
20879 &staDesc);
20880 if (ret != VOS_STATUS_SUCCESS) {
20881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20882 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020883
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020884 /* Mark TDLS client Authenticated .*/
20885 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20886 pTdlsPeer->staId,
20887 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020888 if (VOS_STATUS_SUCCESS == status)
20889 {
Hoonki Lee14621352013-04-16 17:51:19 -070020890 if (pTdlsPeer->is_responder == 0)
20891 {
20892 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020893 tdlsConnInfo_t *tdlsInfo;
20894
20895 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20896
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020897 if (!vos_timer_is_initialized(
20898 &pTdlsPeer->initiatorWaitTimeoutTimer))
20899 {
20900 /* Initialize initiator wait callback */
20901 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020902 &pTdlsPeer->initiatorWaitTimeoutTimer,
20903 VOS_TIMER_TYPE_SW,
20904 wlan_hdd_tdls_initiator_wait_cb,
20905 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020906 }
Hoonki Lee14621352013-04-16 17:51:19 -070020907 wlan_hdd_tdls_timer_restart(pAdapter,
20908 &pTdlsPeer->initiatorWaitTimeoutTimer,
20909 WAIT_TIME_TDLS_INITIATOR);
20910 /* suspend initiator TX until it receives direct packet from the
20911 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020912 ret = WLANTL_SuspendDataTx(
20913 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20914 &staId, NULL);
20915 if (ret != VOS_STATUS_SUCCESS) {
20916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20917 }
Hoonki Lee14621352013-04-16 17:51:19 -070020918 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020919
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020920 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020921 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020922 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020923 suppChannelLen =
20924 tdlsLinkEstablishParams.supportedChannelsLen;
20925
20926 if ((suppChannelLen > 0) &&
20927 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20928 {
20929 tANI_U8 suppPeerChannel = 0;
20930 int i = 0;
20931 for (i = 0U; i < suppChannelLen; i++)
20932 {
20933 suppPeerChannel =
20934 tdlsLinkEstablishParams.supportedChannels[i];
20935
20936 pTdlsPeer->isOffChannelSupported = FALSE;
20937 if (suppPeerChannel ==
20938 pTdlsPeer->peerParams.channel)
20939 {
20940 pTdlsPeer->isOffChannelSupported = TRUE;
20941 break;
20942 }
20943 }
20944 }
20945 else
20946 {
20947 pTdlsPeer->isOffChannelSupported = FALSE;
20948 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020949 }
20950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20951 "%s: TDLS channel switch request for channel "
20952 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020953 "%d isOffChannelSupported %d", __func__,
20954 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020955 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020956 suppChannelLen,
20957 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020958
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020959 /* TDLS Off Channel, Enable tdls channel switch,
20960 when their is only one tdls link and it supports */
20961 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20962 if ((numCurrTdlsPeers == 1) &&
20963 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20964 (TRUE == pTdlsPeer->isOffChannelConfigured))
20965 {
20966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20967 "%s: Send TDLS channel switch request for channel %d",
20968 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020969
20970 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020971 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20972 channel = pTdlsPeer->peerParams.channel;
20973
20974 mutex_unlock(&pHddCtx->tdls_lock);
20975
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020976 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20977 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020978 peerMac,
20979 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020980 TDLS_OFF_CHANNEL_BW_OFFSET,
20981 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020982 if (ret != VOS_STATUS_SUCCESS) {
20983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20984 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020985 }
20986 else
20987 {
20988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20989 "%s: TDLS channel switch request not sent"
20990 " numCurrTdlsPeers %d "
20991 "isOffChannelSupported %d "
20992 "isOffChannelConfigured %d",
20993 __func__, numCurrTdlsPeers,
20994 pTdlsPeer->isOffChannelSupported,
20995 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020996 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020997 }
20998
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020999 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021000 else
21001 mutex_unlock(&pHddCtx->tdls_lock);
21002
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021003 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021004
21005 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021006 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21007 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021008 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021009 int ac;
21010 uint8 ucAc[4] = { WLANTL_AC_VO,
21011 WLANTL_AC_VI,
21012 WLANTL_AC_BK,
21013 WLANTL_AC_BE };
21014 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21015 for(ac=0; ac < 4; ac++)
21016 {
21017 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21018 pTdlsPeer->staId, ucAc[ac],
21019 tlTid[ac], tlTid[ac], 0, 0,
21020 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021021 if (status != VOS_STATUS_SUCCESS) {
21022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21023 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021024 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021025 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021026 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021027
Bhargav Shah66896792015-10-01 18:17:37 +053021028 /* stop TCP delack timer if TDLS is enable */
21029 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21030 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021031 hdd_wlan_tdls_enable_link_event(peer,
21032 pTdlsPeer->isOffChannelSupported,
21033 pTdlsPeer->isOffChannelConfigured,
21034 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021035 }
21036 break;
21037 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021038 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021039 tANI_U16 numCurrTdlsPeers = 0;
21040 hddTdlsPeer_t *connPeer = NULL;
21041
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21043 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21044 __func__, MAC_ADDR_ARRAY(peer));
21045
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021046 mutex_lock(&pHddCtx->tdls_lock);
21047 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021048
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021049
Sunil Dutt41de4e22013-11-14 18:09:02 +053021050 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021051 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21053 " (oper %d) not exsting. ignored",
21054 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21055 return -EINVAL;
21056 }
21057
21058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21059 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21060 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21061 "NL80211_TDLS_DISABLE_LINK");
21062
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021063 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021064 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021065 long status;
21066
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021067 /* set tdls off channel status to false for this peer */
21068 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021069 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21070 eTDLS_LINK_TEARING,
21071 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21072 eTDLS_LINK_UNSPECIFIED:
21073 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021074 mutex_unlock(&pHddCtx->tdls_lock);
21075
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021076 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21077
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021078 status = sme_DeleteTdlsPeerSta(
21079 WLAN_HDD_GET_HAL_CTX(pAdapter),
21080 pAdapter->sessionId, peer );
21081 if (status != VOS_STATUS_SUCCESS) {
21082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21083 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021084
21085 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21086 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021087
21088 mutex_lock(&pHddCtx->tdls_lock);
21089 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21090 if ( NULL == pTdlsPeer ) {
21091 mutex_unlock(&pHddCtx->tdls_lock);
21092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21093 " peer was freed in other context",
21094 __func__, MAC_ADDR_ARRAY(peer));
21095 return -EINVAL;
21096 }
21097
Atul Mittal271a7652014-09-12 13:18:22 +053021098 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021099 eTDLS_LINK_IDLE,
21100 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021101 mutex_unlock(&pHddCtx->tdls_lock);
21102
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021103 if (status <= 0)
21104 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21106 "%s: Del station failed status %ld",
21107 __func__, status);
21108 return -EPERM;
21109 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021110
21111 /* TDLS Off Channel, Enable tdls channel switch,
21112 when their is only one tdls link and it supports */
21113 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21114 if (numCurrTdlsPeers == 1)
21115 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021116 tSirMacAddr peerMac;
21117 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021118
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021119 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021120 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021121
21122 if (connPeer == NULL) {
21123 mutex_unlock(&pHddCtx->tdls_lock);
21124 hddLog(VOS_TRACE_LEVEL_ERROR,
21125 "%s connPeer is NULL", __func__);
21126 return -EINVAL;
21127 }
21128
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021129 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21130 channel = connPeer->peerParams.channel;
21131
21132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21133 "%s: TDLS channel switch "
21134 "isOffChannelSupported %d "
21135 "isOffChannelConfigured %d "
21136 "isOffChannelEstablished %d",
21137 __func__,
21138 (connPeer ? connPeer->isOffChannelSupported : -1),
21139 (connPeer ? connPeer->isOffChannelConfigured : -1),
21140 (connPeer ? connPeer->isOffChannelEstablished : -1));
21141
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021142 if ((connPeer) &&
21143 (connPeer->isOffChannelSupported == TRUE) &&
21144 (connPeer->isOffChannelConfigured == TRUE))
21145 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021146 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021147 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021148 status = sme_SendTdlsChanSwitchReq(
21149 WLAN_HDD_GET_HAL_CTX(pAdapter),
21150 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021151 peerMac,
21152 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021153 TDLS_OFF_CHANNEL_BW_OFFSET,
21154 TDLS_CHANNEL_SWITCH_ENABLE);
21155 if (status != VOS_STATUS_SUCCESS) {
21156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21157 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021158 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021159 else
21160 mutex_unlock(&pHddCtx->tdls_lock);
21161 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021162 else
21163 {
21164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21165 "%s: TDLS channel switch request not sent "
21166 "numCurrTdlsPeers %d ",
21167 __func__, numCurrTdlsPeers);
21168 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021169 }
21170 else
21171 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021172 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21174 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021175 }
Bhargav Shah66896792015-10-01 18:17:37 +053021176 if (numCurrTdlsPeers == 0) {
21177 /* start TCP delack timer if TDLS is disable */
21178 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21179 hdd_manage_delack_timer(pHddCtx);
21180 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021181 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021182 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021183 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021184 {
Atul Mittal115287b2014-07-08 13:26:33 +053021185 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021186
Atul Mittal115287b2014-07-08 13:26:33 +053021187 if (0 != status)
21188 {
21189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021190 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021191 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021192 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021193 break;
21194 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021195 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021196 {
Atul Mittal115287b2014-07-08 13:26:33 +053021197 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21198 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021199 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021200 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021201
Atul Mittal115287b2014-07-08 13:26:33 +053021202 if (0 != status)
21203 {
21204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021205 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021206 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021207 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021208 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021209 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021210 case NL80211_TDLS_DISCOVERY_REQ:
21211 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021213 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021214 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021215 return -ENOTSUPP;
21216 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21218 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021219 return -ENOTSUPP;
21220 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021221
21222 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021223 return 0;
21224}
Chilam NG571c65a2013-01-19 12:27:36 +053021225
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021226static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21228 const u8 *peer,
21229#else
21230 u8 *peer,
21231#endif
21232 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021233{
21234 int ret;
21235
21236 vos_ssr_protect(__func__);
21237 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21238 vos_ssr_unprotect(__func__);
21239
21240 return ret;
21241}
21242
Chilam NG571c65a2013-01-19 12:27:36 +053021243int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21244 struct net_device *dev, u8 *peer)
21245{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021246 hddLog(VOS_TRACE_LEVEL_INFO,
21247 "tdls send discover req: "MAC_ADDRESS_STR,
21248 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021249#if TDLS_MGMT_VERSION2
21250 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21251 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21252#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021253#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21254 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21255 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21256#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21257 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21258 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21259#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21260 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21261 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21262#else
Chilam NG571c65a2013-01-19 12:27:36 +053021263 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21264 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021265#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021266#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021267}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021268#endif
21269
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021270#ifdef WLAN_FEATURE_GTK_OFFLOAD
21271/*
21272 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21273 * Callback rountine called upon receiving response for
21274 * get offload info
21275 */
21276void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21277 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21278{
21279
21280 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021281 tANI_U8 tempReplayCounter[8];
21282 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021283
21284 ENTER();
21285
21286 if (NULL == pAdapter)
21287 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021289 "%s: HDD adapter is Null", __func__);
21290 return ;
21291 }
21292
21293 if (NULL == pGtkOffloadGetInfoRsp)
21294 {
21295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21296 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21297 return ;
21298 }
21299
21300 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21301 {
21302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21303 "%s: wlan Failed to get replay counter value",
21304 __func__);
21305 return ;
21306 }
21307
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021308 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21309 /* Update replay counter */
21310 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21311 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21312
21313 {
21314 /* changing from little to big endian since supplicant
21315 * works on big endian format
21316 */
21317 int i;
21318 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21319
21320 for (i = 0; i < 8; i++)
21321 {
21322 tempReplayCounter[7-i] = (tANI_U8)p[i];
21323 }
21324 }
21325
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021326 /* Update replay counter to NL */
21327 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021328 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021329}
21330
21331/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021332 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021333 * This function is used to offload GTK rekeying job to the firmware.
21334 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021335int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021336 struct cfg80211_gtk_rekey_data *data)
21337{
21338 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21339 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21340 hdd_station_ctx_t *pHddStaCtx;
21341 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021342 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021343 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021344 eHalStatus status = eHAL_STATUS_FAILURE;
21345
21346 ENTER();
21347
21348 if (NULL == pAdapter)
21349 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021351 "%s: HDD adapter is Null", __func__);
21352 return -ENODEV;
21353 }
21354
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021355 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21356 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21357 pAdapter->sessionId, pAdapter->device_mode));
21358
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021359 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021360 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021361 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021362 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021363 }
21364
21365 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21366 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21367 if (NULL == hHal)
21368 {
21369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21370 "%s: HAL context is Null!!!", __func__);
21371 return -EAGAIN;
21372 }
21373
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021374 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21375 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21376 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21377 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021378 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021379 {
21380 /* changing from big to little endian since driver
21381 * works on little endian format
21382 */
21383 tANI_U8 *p =
21384 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21385 int i;
21386
21387 for (i = 0; i < 8; i++)
21388 {
21389 p[7-i] = data->replay_ctr[i];
21390 }
21391 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021392
21393 if (TRUE == pHddCtx->hdd_wlan_suspended)
21394 {
21395 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021396 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21397 sizeof (tSirGtkOffloadParams));
21398 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021399 pAdapter->sessionId);
21400
21401 if (eHAL_STATUS_SUCCESS != status)
21402 {
21403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21404 "%s: sme_SetGTKOffload failed, returned %d",
21405 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021406
21407 /* Need to clear any trace of key value in the memory.
21408 * Thus zero out the memory even though it is local
21409 * variable.
21410 */
21411 vos_mem_zero(&hddGtkOffloadReqParams,
21412 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021413 return status;
21414 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21416 "%s: sme_SetGTKOffload successfull", __func__);
21417 }
21418 else
21419 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21421 "%s: wlan not suspended GTKOffload request is stored",
21422 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021423 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021424
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021425 /* Need to clear any trace of key value in the memory.
21426 * Thus zero out the memory even though it is local
21427 * variable.
21428 */
21429 vos_mem_zero(&hddGtkOffloadReqParams,
21430 sizeof(hddGtkOffloadReqParams));
21431
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021432 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021433 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021434}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021435
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021436int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21437 struct cfg80211_gtk_rekey_data *data)
21438{
21439 int ret;
21440
21441 vos_ssr_protect(__func__);
21442 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21443 vos_ssr_unprotect(__func__);
21444
21445 return ret;
21446}
21447#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021448/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021449 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021450 * This function is used to set access control policy
21451 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021452static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21453 struct net_device *dev,
21454 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021455{
21456 int i;
21457 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21458 hdd_hostapd_state_t *pHostapdState;
21459 tsap_Config_t *pConfig;
21460 v_CONTEXT_t pVosContext = NULL;
21461 hdd_context_t *pHddCtx;
21462 int status;
21463
21464 ENTER();
21465
21466 if (NULL == pAdapter)
21467 {
21468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21469 "%s: HDD adapter is Null", __func__);
21470 return -ENODEV;
21471 }
21472
21473 if (NULL == params)
21474 {
21475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21476 "%s: params is Null", __func__);
21477 return -EINVAL;
21478 }
21479
21480 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21481 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021482 if (0 != status)
21483 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021484 return status;
21485 }
21486
21487 pVosContext = pHddCtx->pvosContext;
21488 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21489
21490 if (NULL == pHostapdState)
21491 {
21492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21493 "%s: pHostapdState is Null", __func__);
21494 return -EINVAL;
21495 }
21496
21497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21498 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021499 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21500 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21501 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021502
21503 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21504 {
21505 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21506
21507 /* default value */
21508 pConfig->num_accept_mac = 0;
21509 pConfig->num_deny_mac = 0;
21510
21511 /**
21512 * access control policy
21513 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21514 * listed in hostapd.deny file.
21515 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21516 * listed in hostapd.accept file.
21517 */
21518 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21519 {
21520 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21521 }
21522 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21523 {
21524 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21525 }
21526 else
21527 {
21528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21529 "%s:Acl Policy : %d is not supported",
21530 __func__, params->acl_policy);
21531 return -ENOTSUPP;
21532 }
21533
21534 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21535 {
21536 pConfig->num_accept_mac = params->n_acl_entries;
21537 for (i = 0; i < params->n_acl_entries; i++)
21538 {
21539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21540 "** Add ACL MAC entry %i in WhiletList :"
21541 MAC_ADDRESS_STR, i,
21542 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21543
21544 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21545 sizeof(qcmacaddr));
21546 }
21547 }
21548 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21549 {
21550 pConfig->num_deny_mac = params->n_acl_entries;
21551 for (i = 0; i < params->n_acl_entries; i++)
21552 {
21553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21554 "** Add ACL MAC entry %i in BlackList :"
21555 MAC_ADDRESS_STR, i,
21556 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21557
21558 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21559 sizeof(qcmacaddr));
21560 }
21561 }
21562
21563 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21564 {
21565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21566 "%s: SAP Set Mac Acl fail", __func__);
21567 return -EINVAL;
21568 }
21569 }
21570 else
21571 {
21572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021573 "%s: Invalid device_mode = %s (%d)",
21574 __func__, hdd_device_modetoString(pAdapter->device_mode),
21575 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021576 return -EINVAL;
21577 }
21578
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021579 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021580 return 0;
21581}
21582
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021583static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21584 struct net_device *dev,
21585 const struct cfg80211_acl_data *params)
21586{
21587 int ret;
21588 vos_ssr_protect(__func__);
21589 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21590 vos_ssr_unprotect(__func__);
21591
21592 return ret;
21593}
21594
Leo Chang9056f462013-08-01 19:21:11 -070021595#ifdef WLAN_NL80211_TESTMODE
21596#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021597void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021598(
21599 void *pAdapter,
21600 void *indCont
21601)
21602{
Leo Changd9df8aa2013-09-26 13:32:26 -070021603 tSirLPHBInd *lphbInd;
21604 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021605 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021606
21607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021608 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021609
c_hpothu73f35e62014-04-18 13:40:08 +053021610 if (pAdapter == NULL)
21611 {
21612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21613 "%s: pAdapter is NULL\n",__func__);
21614 return;
21615 }
21616
Leo Chang9056f462013-08-01 19:21:11 -070021617 if (NULL == indCont)
21618 {
21619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021620 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021621 return;
21622 }
21623
c_hpothu73f35e62014-04-18 13:40:08 +053021624 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021625 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021626 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021627 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021628 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021629 GFP_ATOMIC);
21630 if (!skb)
21631 {
21632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21633 "LPHB timeout, NL buffer alloc fail");
21634 return;
21635 }
21636
Leo Changac3ba772013-10-07 09:47:04 -070021637 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021638 {
21639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21640 "WLAN_HDD_TM_ATTR_CMD put fail");
21641 goto nla_put_failure;
21642 }
Leo Changac3ba772013-10-07 09:47:04 -070021643 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021644 {
21645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21646 "WLAN_HDD_TM_ATTR_TYPE put fail");
21647 goto nla_put_failure;
21648 }
Leo Changac3ba772013-10-07 09:47:04 -070021649 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021650 sizeof(tSirLPHBInd), lphbInd))
21651 {
21652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21653 "WLAN_HDD_TM_ATTR_DATA put fail");
21654 goto nla_put_failure;
21655 }
Leo Chang9056f462013-08-01 19:21:11 -070021656 cfg80211_testmode_event(skb, GFP_ATOMIC);
21657 return;
21658
21659nla_put_failure:
21660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21661 "NLA Put fail");
21662 kfree_skb(skb);
21663
21664 return;
21665}
21666#endif /* FEATURE_WLAN_LPHB */
21667
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021668static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021669{
21670 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21671 int err = 0;
21672#ifdef FEATURE_WLAN_LPHB
21673 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021674 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021675
21676 ENTER();
21677
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021678 err = wlan_hdd_validate_context(pHddCtx);
21679 if (0 != err)
21680 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021681 return err;
21682 }
Leo Chang9056f462013-08-01 19:21:11 -070021683#endif /* FEATURE_WLAN_LPHB */
21684
21685 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21686 if (err)
21687 {
21688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21689 "%s Testmode INV ATTR", __func__);
21690 return err;
21691 }
21692
21693 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21694 {
21695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21696 "%s Testmode INV CMD", __func__);
21697 return -EINVAL;
21698 }
21699
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21701 TRACE_CODE_HDD_CFG80211_TESTMODE,
21702 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021703 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21704 {
21705#ifdef FEATURE_WLAN_LPHB
21706 /* Low Power Heartbeat configuration request */
21707 case WLAN_HDD_TM_CMD_WLAN_HB:
21708 {
21709 int buf_len;
21710 void *buf;
21711 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021712 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021713
21714 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21715 {
21716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21717 "%s Testmode INV DATA", __func__);
21718 return -EINVAL;
21719 }
21720
21721 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21722 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021723
Manjeet Singh3c577442017-02-10 19:03:38 +053021724 if (buf_len > sizeof(*hb_params)) {
21725 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21726 buf_len);
21727 return -ERANGE;
21728 }
21729
Amar Singhal05852702014-02-04 14:40:00 -080021730 hb_params_temp =(tSirLPHBReq *)buf;
21731 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21732 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21733 return -EINVAL;
21734
Leo Chang9056f462013-08-01 19:21:11 -070021735 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21736 if (NULL == hb_params)
21737 {
21738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21739 "%s Request Buffer Alloc Fail", __func__);
21740 return -EINVAL;
21741 }
21742
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021743 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021744 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021745 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21746 hb_params,
21747 wlan_hdd_cfg80211_lphb_ind_handler);
21748 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021749 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21751 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021752 vos_mem_free(hb_params);
21753 }
Leo Chang9056f462013-08-01 19:21:11 -070021754 return 0;
21755 }
21756#endif /* FEATURE_WLAN_LPHB */
21757 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21759 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021760 return -EOPNOTSUPP;
21761 }
21762
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021763 EXIT();
21764 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021765}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021766
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021767static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21769 struct wireless_dev *wdev,
21770#endif
21771 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021772{
21773 int ret;
21774
21775 vos_ssr_protect(__func__);
21776 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21777 vos_ssr_unprotect(__func__);
21778
21779 return ret;
21780}
Leo Chang9056f462013-08-01 19:21:11 -070021781#endif /* CONFIG_NL80211_TESTMODE */
21782
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021783extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021784static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021785 struct net_device *dev,
21786 int idx, struct survey_info *survey)
21787{
21788 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21789 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021790 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021791 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021792 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021793 v_S7_t snr,rssi;
21794 int status, i, j, filled = 0;
21795
21796 ENTER();
21797
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021798 if (NULL == pAdapter)
21799 {
21800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21801 "%s: HDD adapter is Null", __func__);
21802 return -ENODEV;
21803 }
21804
21805 if (NULL == wiphy)
21806 {
21807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21808 "%s: wiphy is Null", __func__);
21809 return -ENODEV;
21810 }
21811
21812 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21813 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021814 if (0 != status)
21815 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021816 return status;
21817 }
21818
Mihir Sheted9072e02013-08-21 17:02:29 +053021819 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21820
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021821 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021822 0 != pAdapter->survey_idx ||
21823 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021824 {
21825 /* The survey dump ops when implemented completely is expected to
21826 * return a survey of all channels and the ops is called by the
21827 * kernel with incremental values of the argument 'idx' till it
21828 * returns -ENONET. But we can only support the survey for the
21829 * operating channel for now. survey_idx is used to track
21830 * that the ops is called only once and then return -ENONET for
21831 * the next iteration
21832 */
21833 pAdapter->survey_idx = 0;
21834 return -ENONET;
21835 }
21836
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021837 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21838 {
21839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21840 "%s: Roaming in progress, hence return ", __func__);
21841 return -ENONET;
21842 }
21843
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021844 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21845
21846 wlan_hdd_get_snr(pAdapter, &snr);
21847 wlan_hdd_get_rssi(pAdapter, &rssi);
21848
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021849 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21850 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21851 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021852 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21853 hdd_wlan_get_freq(channel, &freq);
21854
21855
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021856 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021857 {
21858 if (NULL == wiphy->bands[i])
21859 {
21860 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21861 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21862 continue;
21863 }
21864
21865 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21866 {
21867 struct ieee80211_supported_band *band = wiphy->bands[i];
21868
21869 if (band->channels[j].center_freq == (v_U16_t)freq)
21870 {
21871 survey->channel = &band->channels[j];
21872 /* The Rx BDs contain SNR values in dB for the received frames
21873 * while the supplicant expects noise. So we calculate and
21874 * return the value of noise (dBm)
21875 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21876 */
21877 survey->noise = rssi - snr;
21878 survey->filled = SURVEY_INFO_NOISE_DBM;
21879 filled = 1;
21880 }
21881 }
21882 }
21883
21884 if (filled)
21885 pAdapter->survey_idx = 1;
21886 else
21887 {
21888 pAdapter->survey_idx = 0;
21889 return -ENONET;
21890 }
21891
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021892 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021893 return 0;
21894}
21895
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021896static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21897 struct net_device *dev,
21898 int idx, struct survey_info *survey)
21899{
21900 int ret;
21901
21902 vos_ssr_protect(__func__);
21903 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21904 vos_ssr_unprotect(__func__);
21905
21906 return ret;
21907}
21908
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021909/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021910 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021911 * this is called when cfg80211 driver resume
21912 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21913 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021914int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021915{
21916 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21917 hdd_adapter_t *pAdapter;
21918 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21919 VOS_STATUS status = VOS_STATUS_SUCCESS;
21920
21921 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021922
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021923 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021924 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021925 return 0;
21926 }
21927
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021928 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21929 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021930
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021931 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021932 {
21933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21934 "%s: Resume SoftAP", __func__);
21935 hdd_set_wlan_suspend_mode(false);
21936 }
21937
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021938 spin_lock(&pHddCtx->schedScan_lock);
21939 pHddCtx->isWiphySuspended = FALSE;
21940 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21941 {
21942 spin_unlock(&pHddCtx->schedScan_lock);
21943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21944 "%s: Return resume is not due to PNO indication", __func__);
21945 return 0;
21946 }
21947 // Reset flag to avoid updatating cfg80211 data old results again
21948 pHddCtx->isSchedScanUpdatePending = FALSE;
21949 spin_unlock(&pHddCtx->schedScan_lock);
21950
21951 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21952
21953 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21954 {
21955 pAdapter = pAdapterNode->pAdapter;
21956 if ( (NULL != pAdapter) &&
21957 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21958 {
21959 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021960 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21962 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021963 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021964 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021965 {
21966 /* Acquire wakelock to handle the case where APP's tries to
21967 * suspend immediately after updating the scan results. Whis
21968 * results in app's is in suspended state and not able to
21969 * process the connect request to AP
21970 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021971 hdd_prevent_suspend_timeout(2000,
21972 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021973 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021974 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021975
21976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21977 "%s : cfg80211 scan result database updated", __func__);
21978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021979 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021980 return 0;
21981
21982 }
21983 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21984 pAdapterNode = pNext;
21985 }
21986
21987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21988 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021989 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021990 return 0;
21991}
21992
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021993int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21994{
21995 int ret;
21996
21997 vos_ssr_protect(__func__);
21998 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21999 vos_ssr_unprotect(__func__);
22000
22001 return ret;
22002}
22003
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022004/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022005 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022006 * this is called when cfg80211 driver suspends
22007 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022008int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022009 struct cfg80211_wowlan *wow)
22010{
22011 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022012 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022013
22014 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022015
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022016 ret = wlan_hdd_validate_context(pHddCtx);
22017 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022018 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022019 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022020 }
22021
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022022 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22024 "%s: Suspend SoftAP", __func__);
22025 hdd_set_wlan_suspend_mode(true);
22026 }
22027
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022028
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022029 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22030 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22031 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022032 pHddCtx->isWiphySuspended = TRUE;
22033
22034 EXIT();
22035
22036 return 0;
22037}
22038
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022039int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22040 struct cfg80211_wowlan *wow)
22041{
22042 int ret;
22043
22044 vos_ssr_protect(__func__);
22045 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22046 vos_ssr_unprotect(__func__);
22047
22048 return ret;
22049}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022050
22051#ifdef FEATURE_OEM_DATA_SUPPORT
22052static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022053 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022054{
22055 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22056
22057 ENTER();
22058
22059 if (wlan_hdd_validate_context(pHddCtx)) {
22060 return;
22061 }
22062 if (!pMsg)
22063 {
22064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22065 return;
22066 }
22067
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022068 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022069
22070 EXIT();
22071 return;
22072
22073}
22074
22075void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022076 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022077{
22078 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22079
22080 ENTER();
22081
22082 if (wlan_hdd_validate_context(pHddCtx)) {
22083 return;
22084 }
22085
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022087
22088 switch(evType) {
22089 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022090 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022091 break;
22092 default:
22093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22094 break;
22095 }
22096 EXIT();
22097}
22098#endif
22099
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022100#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22101 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022102/**
22103 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22104 * @wiphy: Pointer to wiphy
22105 * @wdev: Pointer to wireless device structure
22106 *
22107 * This function is used to abort an ongoing scan
22108 *
22109 * Return: None
22110 */
22111static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22112 struct wireless_dev *wdev)
22113{
22114 struct net_device *dev = wdev->netdev;
22115 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22116 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22117 int ret;
22118
22119 ENTER();
22120
22121 if (NULL == adapter) {
22122 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22123 return;
22124 }
22125
22126 ret = wlan_hdd_validate_context(hdd_ctx);
22127 if (0 != ret)
22128 return;
22129
22130 wlan_hdd_scan_abort(adapter);
22131
22132 return;
22133}
22134
22135/**
22136 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22137 * @wiphy: Pointer to wiphy
22138 * @wdev: Pointer to wireless device structure
22139 *
22140 * Return: None
22141 */
22142void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22143 struct wireless_dev *wdev)
22144{
22145 vos_ssr_protect(__func__);
22146 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22147 vos_ssr_unprotect(__func__);
22148
22149 return;
22150}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022151#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022152
Abhishek Singh936c6932017-11-07 17:28:23 +053022153#ifdef CHANNEL_SWITCH_SUPPORTED
22154/**
22155 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22156 * channel in SAP/GO
22157 * @wiphy: wiphy pointer
22158 * @dev: dev pointer.
22159 * @csa_params: Change channel params
22160 *
22161 * This function is called to switch channel in SAP/GO
22162 *
22163 * Return: 0 if success else return non zero
22164 */
22165static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22166 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22167{
22168 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22169 hdd_context_t *hdd_ctx;
22170 uint8_t channel;
22171 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022172 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022173 v_CONTEXT_t vos_ctx;
22174
22175 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22176
22177 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22178 ret = wlan_hdd_validate_context(hdd_ctx);
22179 if (ret)
22180 return ret;
22181
22182 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22183 if (!vos_ctx) {
22184 hddLog(LOGE, FL("Vos ctx is null"));
22185 return -EINVAL;
22186 }
22187
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022188 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022189 return -ENOTSUPP;
22190
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022191 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22192 if (!sap_ctx) {
22193 hddLog(LOGE, FL("sap_ctx is NULL"));
22194 return -EINVAL;
22195 }
22196
22197 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22198 if (ret)
22199 return ret;
22200
22201 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22202
Abhishek Singh936c6932017-11-07 17:28:23 +053022203 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022204 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022205
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022206 if (ret) {
22207 wlansap_reset_chan_change_in_progress(sap_ctx);
22208 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22209 }
22210
Abhishek Singh936c6932017-11-07 17:28:23 +053022211 return ret;
22212}
22213
22214/**
22215 * wlan_hdd_cfg80211_channel_switch()- function to switch
22216 * channel in SAP/GO
22217 * @wiphy: wiphy pointer
22218 * @dev: dev pointer.
22219 * @csa_params: Change channel params
22220 *
22221 * This function is called to switch channel in SAP/GO
22222 *
22223 * Return: 0 if success else return non zero
22224 */
22225static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22226 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22227{
22228 int ret;
22229
22230 vos_ssr_protect(__func__);
22231 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22232 vos_ssr_unprotect(__func__);
22233
22234 return ret;
22235}
22236#endif
22237
Jeff Johnson295189b2012-06-20 16:38:30 -070022238/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022239static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022240{
22241 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22242 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22243 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22244 .change_station = wlan_hdd_change_station,
22245#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22246 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22247 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22248 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022249#else
22250 .start_ap = wlan_hdd_cfg80211_start_ap,
22251 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22252 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022253#endif
22254 .change_bss = wlan_hdd_cfg80211_change_bss,
22255 .add_key = wlan_hdd_cfg80211_add_key,
22256 .get_key = wlan_hdd_cfg80211_get_key,
22257 .del_key = wlan_hdd_cfg80211_del_key,
22258 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022259#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022260 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022262 .scan = wlan_hdd_cfg80211_scan,
22263 .connect = wlan_hdd_cfg80211_connect,
22264 .disconnect = wlan_hdd_cfg80211_disconnect,
22265 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22266 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22267 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22268 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22269 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022270 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22271 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022272 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22274 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22275 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22276 .set_txq_params = wlan_hdd_set_txq_params,
22277#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022278 .get_station = wlan_hdd_cfg80211_get_station,
22279 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22280 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022281 .add_station = wlan_hdd_cfg80211_add_station,
22282#ifdef FEATURE_WLAN_LFR
22283 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22284 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22285 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22286#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022287#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22288 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22289#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022290#ifdef FEATURE_WLAN_TDLS
22291 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22292 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22293#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022294#ifdef WLAN_FEATURE_GTK_OFFLOAD
22295 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22296#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022297#ifdef FEATURE_WLAN_SCAN_PNO
22298 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22299 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22300#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022301 .resume = wlan_hdd_cfg80211_resume_wlan,
22302 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022303 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022304#ifdef WLAN_NL80211_TESTMODE
22305 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22306#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022307 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022308#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22309 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022310 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022311#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022312#ifdef CHANNEL_SWITCH_SUPPORTED
22313 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22314#endif
22315
Jeff Johnson295189b2012-06-20 16:38:30 -070022316};
22317