blob: e92b5b7dc75ba8dc0f39b886f19f137417b63d95 [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
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
463static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
464 .flags = WIPHY_WOWLAN_MAGIC_PKT,
465 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
466 .pattern_min_len = 1,
467 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
468};
469#endif
470
Jeff Johnson295189b2012-06-20 16:38:30 -0700471static struct cfg80211_ops wlan_hdd_cfg80211_ops;
472
473/* Data rate 100KBPS based on IE Index */
474struct index_data_rate_type
475{
476 v_U8_t beacon_rate_index;
477 v_U16_t supported_rate[4];
478};
479
480/* 11B, 11G Rate table include Basic rate and Extended rate
481 The IDX field is the rate index
482 The HI field is the rate when RSSI is strong or being ignored
483 (in this case we report actual rate)
484 The MID field is the rate when RSSI is moderate
485 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
486 The LO field is the rate when RSSI is low
487 (in this case we don't report rates, actual current rate used)
488 */
489static const struct
490{
491 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700492 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700493} supported_data_rate[] =
494{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700495/* IDX HI HM LM LO (RSSI-based index */
496 {2, { 10, 10, 10, 0}},
497 {4, { 20, 20, 10, 0}},
498 {11, { 55, 20, 10, 0}},
499 {12, { 60, 55, 20, 0}},
500 {18, { 90, 55, 20, 0}},
501 {22, {110, 55, 20, 0}},
502 {24, {120, 90, 60, 0}},
503 {36, {180, 120, 60, 0}},
504 {44, {220, 180, 60, 0}},
505 {48, {240, 180, 90, 0}},
506 {66, {330, 180, 90, 0}},
507 {72, {360, 240, 90, 0}},
508 {96, {480, 240, 120, 0}},
509 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700510};
511
512/* MCS Based rate table */
513static struct index_data_rate_type supported_mcs_rate[] =
514{
515/* MCS L20 L40 S20 S40 */
516 {0, {65, 135, 72, 150}},
517 {1, {130, 270, 144, 300}},
518 {2, {195, 405, 217, 450}},
519 {3, {260, 540, 289, 600}},
520 {4, {390, 810, 433, 900}},
521 {5, {520, 1080, 578, 1200}},
522 {6, {585, 1215, 650, 1350}},
523 {7, {650, 1350, 722, 1500}}
524};
525
Leo Chang6f8870f2013-03-26 18:11:36 -0700526#ifdef WLAN_FEATURE_11AC
527
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530528#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700529
530struct index_vht_data_rate_type
531{
532 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530533 v_U16_t supported_VHT80_rate[2];
534 v_U16_t supported_VHT40_rate[2];
535 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700536};
537
538typedef enum
539{
540 DATA_RATE_11AC_MAX_MCS_7,
541 DATA_RATE_11AC_MAX_MCS_8,
542 DATA_RATE_11AC_MAX_MCS_9,
543 DATA_RATE_11AC_MAX_MCS_NA
544} eDataRate11ACMaxMcs;
545
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530546/* SSID broadcast type */
547typedef enum eSSIDBcastType
548{
549 eBCAST_UNKNOWN = 0,
550 eBCAST_NORMAL = 1,
551 eBCAST_HIDDEN = 2,
552} tSSIDBcastType;
553
Leo Chang6f8870f2013-03-26 18:11:36 -0700554/* MCS Based VHT rate table */
555static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
556{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530557/* MCS L80 S80 L40 S40 L20 S40*/
558 {0, {293, 325}, {135, 150}, {65, 72}},
559 {1, {585, 650}, {270, 300}, {130, 144}},
560 {2, {878, 975}, {405, 450}, {195, 217}},
561 {3, {1170, 1300}, {540, 600}, {260, 289}},
562 {4, {1755, 1950}, {810, 900}, {390, 433}},
563 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
564 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
565 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
566 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
567 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700568};
569#endif /* WLAN_FEATURE_11AC */
570
c_hpothu79aab322014-07-14 21:11:01 +0530571/*array index points to MCS and array value points respective rssi*/
572static int rssiMcsTbl[][10] =
573{
574/*MCS 0 1 2 3 4 5 6 7 8 9*/
575 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
576 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
577 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
578};
579
Jeff Johnson295189b2012-06-20 16:38:30 -0700580extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530581#ifdef FEATURE_WLAN_SCAN_PNO
582static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700584
Leo Chang9056f462013-08-01 19:21:11 -0700585#ifdef WLAN_NL80211_TESTMODE
586enum wlan_hdd_tm_attr
587{
588 WLAN_HDD_TM_ATTR_INVALID = 0,
589 WLAN_HDD_TM_ATTR_CMD = 1,
590 WLAN_HDD_TM_ATTR_DATA = 2,
591 WLAN_HDD_TM_ATTR_TYPE = 3,
592 /* keep last */
593 WLAN_HDD_TM_ATTR_AFTER_LAST,
594 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
595};
596
597enum wlan_hdd_tm_cmd
598{
599 WLAN_HDD_TM_CMD_WLAN_HB = 1,
600};
601
602#define WLAN_HDD_TM_DATA_MAX_LEN 5000
603
604static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
605{
606 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
607 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
608 .len = WLAN_HDD_TM_DATA_MAX_LEN },
609};
610#endif /* WLAN_NL80211_TESTMODE */
611
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800612#ifdef FEATURE_WLAN_CH_AVOID
613/*
614 * FUNCTION: wlan_hdd_send_avoid_freq_event
615 * This is called when wlan driver needs to send vendor specific
616 * avoid frequency range event to userspace
617 */
618int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
619 tHddAvoidFreqList *pAvoidFreqList)
620{
621 struct sk_buff *vendor_event;
622
623 ENTER();
624
625 if (!pHddCtx)
626 {
627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
628 "%s: HDD context is null", __func__);
629 return -1;
630 }
631
632 if (!pAvoidFreqList)
633 {
634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
635 "%s: pAvoidFreqList is null", __func__);
636 return -1;
637 }
638
639 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
641 NULL,
642#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800643 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530644 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800645 GFP_KERNEL);
646 if (!vendor_event)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 "%s: cfg80211_vendor_event_alloc failed", __func__);
650 return -1;
651 }
652
653 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
654 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
655
656 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
657
658 EXIT();
659 return 0;
660}
661#endif /* FEATURE_WLAN_CH_AVOID */
662
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530664 * define short names for the global vendor params
665 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
666 */
667#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
668
669/**
670 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
671 * hang reason
672 * @reason: cds recovery reason
673 *
674 * Return: Vendor specific reason code
675 */
676static enum qca_wlan_vendor_hang_reason
677hdd_convert_hang_reason(enum vos_hang_reason reason)
678{
679 unsigned int ret_val;
680
681 switch (reason) {
682 case VOS_GET_MSG_BUFF_FAILURE:
683 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
684 break;
685 case VOS_ACTIVE_LIST_TIMEOUT:
686 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
687 break;
688 case VOS_SCAN_REQ_EXPIRED:
689 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
690 break;
691 case VOS_TRANSMISSIONS_TIMEOUT:
692 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
693 break;
694 case VOS_DXE_FAILURE:
695 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
696 break;
697 case VOS_WDI_FAILURE:
698 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
699 break;
700 case VOS_REASON_UNSPECIFIED:
701 default:
702 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
703 }
704 return ret_val;
705}
706
707/**
708 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
709 * @hdd_ctx: Pointer to hdd context
710 * @reason: cds recovery reason
711 *
712 * Return: 0 on success or failure reason
713 */
714int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
715 enum vos_hang_reason reason)
716{
717 struct sk_buff *vendor_event;
718 enum qca_wlan_vendor_hang_reason hang_reason;
719
720 ENTER();
721
722 if (!hdd_ctx) {
723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
724 "HDD context is null");
725 return -EINVAL;
726 }
727
728 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
730 NULL,
731#endif
732 sizeof(unsigned int),
733 HANG_REASON_INDEX,
734 GFP_KERNEL);
735 if (!vendor_event) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "cfg80211_vendor_event_alloc failed");
738 return -ENOMEM;
739 }
740
741 hang_reason = hdd_convert_hang_reason(reason);
742
743 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
744 (unsigned int) hang_reason)) {
745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
746 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
747 kfree_skb(vendor_event);
748 return -EINVAL;
749 }
750
751 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
752
753 EXIT();
754 return 0;
755}
756#undef HANG_REASON_INDEX
757
758/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 * FUNCTION: __wlan_hdd_cfg80211_nan_request
760 * This is called when wlan driver needs to send vendor specific
761 * nan request event.
762 */
763static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
764 struct wireless_dev *wdev,
765 const void *data, int data_len)
766{
767 tNanRequestReq nan_req;
768 VOS_STATUS status;
769 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530770 struct net_device *dev = wdev->netdev;
771 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
772 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530773 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
774
775 if (0 == data_len)
776 {
777 hddLog(VOS_TRACE_LEVEL_ERROR,
778 FL("NAN - Invalid Request, length = 0"));
779 return ret_val;
780 }
781
782 if (NULL == data)
783 {
784 hddLog(VOS_TRACE_LEVEL_ERROR,
785 FL("NAN - Invalid Request, data is NULL"));
786 return ret_val;
787 }
788
789 status = wlan_hdd_validate_context(pHddCtx);
790 if (0 != status)
791 {
792 hddLog(VOS_TRACE_LEVEL_ERROR,
793 FL("HDD context is not valid"));
794 return -EINVAL;
795 }
796
797 hddLog(LOG1, FL("Received NAN command"));
798 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
799 (tANI_U8 *)data, data_len);
800
801 /* check the NAN Capability */
802 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
803 {
804 hddLog(VOS_TRACE_LEVEL_ERROR,
805 FL("NAN is not supported by Firmware"));
806 return -EINVAL;
807 }
808
809 nan_req.request_data_len = data_len;
810 nan_req.request_data = data;
811
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530812 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530813 if (VOS_STATUS_SUCCESS == status)
814 {
815 ret_val = 0;
816 }
817 return ret_val;
818}
819
820/*
821 * FUNCTION: wlan_hdd_cfg80211_nan_request
822 * Wrapper to protect the nan vendor command from ssr
823 */
824static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
825 struct wireless_dev *wdev,
826 const void *data, int data_len)
827{
828 int ret;
829
830 vos_ssr_protect(__func__);
831 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
832 vos_ssr_unprotect(__func__);
833
834 return ret;
835}
836
837/*
838 * FUNCTION: wlan_hdd_cfg80211_nan_callback
839 * This is a callback function and it gets called
840 * when we need to report nan response event to
841 * upper layers.
842 */
843static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
844{
845 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
846 struct sk_buff *vendor_event;
847 int status;
848 tSirNanEvent *data;
849
850 ENTER();
851 if (NULL == msg)
852 {
853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
854 FL(" msg received here is null"));
855 return;
856 }
857 data = msg;
858
859 status = wlan_hdd_validate_context(pHddCtx);
860
861 if (0 != status)
862 {
863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
864 FL("HDD context is not valid"));
865 return;
866 }
867
868 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
870 NULL,
871#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530872 data->event_data_len +
873 NLMSG_HDRLEN,
874 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
875 GFP_KERNEL);
876
877 if (!vendor_event)
878 {
879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
880 FL("cfg80211_vendor_event_alloc failed"));
881 return;
882 }
883 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
884 data->event_data_len, data->event_data))
885 {
886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
887 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
888 kfree_skb(vendor_event);
889 return;
890 }
891 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
892 EXIT();
893}
894
895/*
896 * FUNCTION: wlan_hdd_cfg80211_nan_init
897 * This function is called to register the callback to sme layer
898 */
899inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
900{
901 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
902}
903
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530904/*
905 * define short names for the global vendor params
906 * used by __wlan_hdd_cfg80211_get_station_cmd()
907 */
908#define STATION_INVALID \
909 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
910#define STATION_INFO \
911 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
912#define STATION_ASSOC_FAIL_REASON \
913 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530914#define STATION_REMOTE \
915 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530916#define STATION_MAX \
917 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
918
919static const struct nla_policy
920hdd_get_station_policy[STATION_MAX + 1] = {
921 [STATION_INFO] = {.type = NLA_FLAG},
922 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
923};
924
925/**
926 * hdd_get_station_assoc_fail() - Handle get station assoc fail
927 * @hdd_ctx: HDD context within host driver
928 * @wdev: wireless device
929 *
930 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
931 * Validate cmd attributes and send the station info to upper layers.
932 *
933 * Return: Success(0) or reason code for failure
934 */
935static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
936 hdd_adapter_t *adapter)
937{
938 struct sk_buff *skb = NULL;
939 uint32_t nl_buf_len;
940 hdd_station_ctx_t *hdd_sta_ctx;
941
942 nl_buf_len = NLMSG_HDRLEN;
943 nl_buf_len += sizeof(uint32_t);
944 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
945
946 if (!skb) {
947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
948 return -ENOMEM;
949 }
950
951 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
952
953 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
954 hdd_sta_ctx->conn_info.assoc_status_code)) {
955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
956 goto fail;
957 }
958 return cfg80211_vendor_cmd_reply(skb);
959fail:
960 if (skb)
961 kfree_skb(skb);
962 return -EINVAL;
963}
964
965/**
966 * hdd_map_auth_type() - transform auth type specific to
967 * vendor command
968 * @auth_type: csr auth type
969 *
970 * Return: Success(0) or reason code for failure
971 */
972static int hdd_convert_auth_type(uint32_t auth_type)
973{
974 uint32_t ret_val;
975
976 switch (auth_type) {
977 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
978 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
979 break;
980 case eCSR_AUTH_TYPE_SHARED_KEY:
981 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
982 break;
983 case eCSR_AUTH_TYPE_WPA:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
985 break;
986 case eCSR_AUTH_TYPE_WPA_PSK:
987 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
988 break;
989 case eCSR_AUTH_TYPE_AUTOSWITCH:
990 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
991 break;
992 case eCSR_AUTH_TYPE_WPA_NONE:
993 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
994 break;
995 case eCSR_AUTH_TYPE_RSN:
996 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
997 break;
998 case eCSR_AUTH_TYPE_RSN_PSK:
999 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1000 break;
1001 case eCSR_AUTH_TYPE_FT_RSN:
1002 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1003 break;
1004 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1005 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1006 break;
1007 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1008 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1009 break;
1010 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1011 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1012 break;
1013#ifdef FEATURE_WLAN_ESE
1014 case eCSR_AUTH_TYPE_CCKM_WPA:
1015 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1016 break;
1017 case eCSR_AUTH_TYPE_CCKM_RSN:
1018 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1019 break;
1020#endif
1021 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1022 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1023 break;
1024 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1025 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1026 break;
1027 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1028 case eCSR_AUTH_TYPE_FAILED:
1029 case eCSR_AUTH_TYPE_NONE:
1030 default:
1031 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1032 break;
1033 }
1034 return ret_val;
1035}
1036
1037/**
1038 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1039 * vendor command
1040 * @dot11mode: dot11mode
1041 *
1042 * Return: Success(0) or reason code for failure
1043 */
1044static int hdd_convert_dot11mode(uint32_t dot11mode)
1045{
1046 uint32_t ret_val;
1047
1048 switch (dot11mode) {
1049 case eCSR_CFG_DOT11_MODE_11A:
1050 ret_val = QCA_WLAN_802_11_MODE_11A;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11B:
1053 ret_val = QCA_WLAN_802_11_MODE_11B;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_11G:
1056 ret_val = QCA_WLAN_802_11_MODE_11G;
1057 break;
1058 case eCSR_CFG_DOT11_MODE_11N:
1059 ret_val = QCA_WLAN_802_11_MODE_11N;
1060 break;
1061 case eCSR_CFG_DOT11_MODE_11AC:
1062 ret_val = QCA_WLAN_802_11_MODE_11AC;
1063 break;
1064 case eCSR_CFG_DOT11_MODE_AUTO:
1065 case eCSR_CFG_DOT11_MODE_ABG:
1066 default:
1067 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1068 }
1069 return ret_val;
1070}
1071
1072/**
1073 * hdd_add_tx_bitrate() - add tx bitrate attribute
1074 * @skb: pointer to sk buff
1075 * @hdd_sta_ctx: pointer to hdd station context
1076 * @idx: attribute index
1077 *
1078 * Return: Success(0) or reason code for failure
1079 */
1080static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1081 hdd_station_ctx_t *hdd_sta_ctx,
1082 int idx)
1083{
1084 struct nlattr *nla_attr;
1085 uint32_t bitrate, bitrate_compat;
1086
1087 nla_attr = nla_nest_start(skb, idx);
1088 if (!nla_attr)
1089 goto fail;
1090 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301091 bitrate = cfg80211_calculate_bitrate(
1092 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301093
1094 /* report 16-bit bitrate only if we can */
1095 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1096 if (bitrate > 0 &&
1097 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1099 goto fail;
1100 }
1101 if (bitrate_compat > 0 &&
1102 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1104 goto fail;
1105 }
1106 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301107 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1109 goto fail;
1110 }
1111 nla_nest_end(skb, nla_attr);
1112 return 0;
1113fail:
1114 return -EINVAL;
1115}
1116
1117/**
1118 * hdd_add_sta_info() - add station info attribute
1119 * @skb: pointer to sk buff
1120 * @hdd_sta_ctx: pointer to hdd station context
1121 * @idx: attribute index
1122 *
1123 * Return: Success(0) or reason code for failure
1124 */
1125static int32_t hdd_add_sta_info(struct sk_buff *skb,
1126 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1127{
1128 struct nlattr *nla_attr;
1129
1130 nla_attr = nla_nest_start(skb, idx);
1131 if (!nla_attr)
1132 goto fail;
1133 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301134 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1136 goto fail;
1137 }
1138 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1139 goto fail;
1140 nla_nest_end(skb, nla_attr);
1141 return 0;
1142fail:
1143 return -EINVAL;
1144}
1145
1146/**
1147 * hdd_add_survey_info() - add survey info attribute
1148 * @skb: pointer to sk buff
1149 * @hdd_sta_ctx: pointer to hdd station context
1150 * @idx: attribute index
1151 *
1152 * Return: Success(0) or reason code for failure
1153 */
1154static int32_t hdd_add_survey_info(struct sk_buff *skb,
1155 hdd_station_ctx_t *hdd_sta_ctx,
1156 int idx)
1157{
1158 struct nlattr *nla_attr;
1159
1160 nla_attr = nla_nest_start(skb, idx);
1161 if (!nla_attr)
1162 goto fail;
1163 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301164 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301165 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301166 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1168 goto fail;
1169 }
1170 nla_nest_end(skb, nla_attr);
1171 return 0;
1172fail:
1173 return -EINVAL;
1174}
1175
1176/**
1177 * hdd_add_link_standard_info() - add link info attribute
1178 * @skb: pointer to sk buff
1179 * @hdd_sta_ctx: pointer to hdd station context
1180 * @idx: attribute index
1181 *
1182 * Return: Success(0) or reason code for failure
1183 */
1184static int32_t
1185hdd_add_link_standard_info(struct sk_buff *skb,
1186 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1187{
1188 struct nlattr *nla_attr;
1189
1190 nla_attr = nla_nest_start(skb, idx);
1191 if (!nla_attr)
1192 goto fail;
1193 if (nla_put(skb,
1194 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301195 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1196 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1198 goto fail;
1199 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301200 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1201 hdd_sta_ctx->cache_conn_info.bssId))
1202 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301203 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1204 goto fail;
1205 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1206 goto fail;
1207 nla_nest_end(skb, nla_attr);
1208 return 0;
1209fail:
1210 return -EINVAL;
1211}
1212
1213/**
1214 * hdd_add_ap_standard_info() - add ap info attribute
1215 * @skb: pointer to sk buff
1216 * @hdd_sta_ctx: pointer to hdd station context
1217 * @idx: attribute index
1218 *
1219 * Return: Success(0) or reason code for failure
1220 */
1221static int32_t
1222hdd_add_ap_standard_info(struct sk_buff *skb,
1223 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1224{
1225 struct nlattr *nla_attr;
1226
1227 nla_attr = nla_nest_start(skb, idx);
1228 if (!nla_attr)
1229 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301231 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301232 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1233 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1235 goto fail;
1236 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301237 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301238 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301239 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1240 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1242 goto fail;
1243 }
1244 nla_nest_end(skb, nla_attr);
1245 return 0;
1246fail:
1247 return -EINVAL;
1248}
1249
1250/**
1251 * hdd_get_station_info() - send BSS information to supplicant
1252 * @hdd_ctx: pointer to hdd context
1253 * @adapter: pointer to adapter
1254 *
1255 * Return: 0 if success else error status
1256 */
1257static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1258 hdd_adapter_t *adapter)
1259{
1260 struct sk_buff *skb = NULL;
1261 uint8_t *tmp_hs20 = NULL;
1262 uint32_t nl_buf_len;
1263 hdd_station_ctx_t *hdd_sta_ctx;
1264
1265 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1266
1267 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301268
1269 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1270 VOS_MAC_ADDR_SIZE +
1271 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1272 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1273 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301274 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301275 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1276 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1277 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1278 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1279 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1280 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1284 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1285 cache_conn_info.hs20vendor_ie);
1286 nl_buf_len +=
1287 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301288 1);
1289 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301290 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1291 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1292 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1293 nl_buf_len +=
1294 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301295
1296
1297 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1298 if (!skb) {
1299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1300 __func__, __LINE__);
1301 return -ENOMEM;
1302 }
1303
1304 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1305 LINK_INFO_STANDARD_NL80211_ATTR)) {
1306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1307 goto fail;
1308 }
1309 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1310 AP_INFO_STANDARD_NL80211_ATTR)) {
1311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1312 goto fail;
1313 }
1314 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301315 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301316 nla_put_u32(skb, INFO_AKM,
1317 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301319 nla_put_u32(skb, WLAN802_11_MODE,
1320 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301321 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1323 goto fail;
1324 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301326 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301327 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1328 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1330 goto fail;
1331 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301332 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301333 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301334 (sizeof(hdd_sta_ctx->
1335 cache_conn_info.vht_operation)),
1336 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1338 goto fail;
1339 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301340 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301341 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301342 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1343 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1345 goto fail;
1346 }
1347
1348 return cfg80211_vendor_cmd_reply(skb);
1349fail:
1350 if (skb)
1351 kfree_skb(skb);
1352 return -EINVAL;
1353}
1354
1355/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301356 * hdd_add_survey_info_sap_get_len - get data length used in
1357 * hdd_add_survey_info_sap()
1358 *
1359 * This function calculates the data length used in hdd_add_survey_info_sap()
1360 *
1361 * Return: total data length used in hdd_add_survey_info_sap()
1362 */
1363static uint32_t hdd_add_survey_info_sap_get_len(void)
1364{
1365 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1366}
1367
1368/**
1369 * hdd_add_survey_info - add survey info attribute
1370 * @skb: pointer to response skb buffer
1371 * @stainfo: station information
1372 * @idx: attribute type index for nla_next_start()
1373 *
1374 * This function adds survey info attribute to response skb buffer
1375 *
1376 * Return : 0 on success and errno on failure
1377 */
1378static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1379 struct hdd_cache_sta_info *stainfo,
1380 int idx)
1381{
1382 struct nlattr *nla_attr;
1383
1384 nla_attr = nla_nest_start(skb, idx);
1385 if (!nla_attr)
1386 goto fail;
1387 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1388 stainfo->freq)) {
1389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1390 FL("put fail"));
1391 goto fail;
1392 }
1393 nla_nest_end(skb, nla_attr);
1394 return 0;
1395fail:
1396 return -EINVAL;
1397}
1398
1399/**
1400 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1401 * hdd_add_tx_bitrate_sap()
1402 *
1403 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1404 *
1405 * Return: total data length used in hdd_add_tx_bitrate_sap()
1406 */
1407static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1408{
1409 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1410}
1411
1412/**
1413 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1414 * @skb: pointer to response skb buffer
1415 * @stainfo: station information
1416 * @idx: attribute type index for nla_next_start()
1417 *
1418 * This function adds vht nss attribute to response skb buffer
1419 *
1420 * Return : 0 on success and errno on failure
1421 */
1422static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1423 struct hdd_cache_sta_info *stainfo,
1424 int idx)
1425{
1426 struct nlattr *nla_attr;
1427
1428 nla_attr = nla_nest_start(skb, idx);
1429 if (!nla_attr)
1430 goto fail;
1431
1432 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1433 stainfo->nss)) {
1434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1435 FL("put fail"));
1436 goto fail;
1437 }
1438 nla_nest_end(skb, nla_attr);
1439 return 0;
1440fail:
1441 return -EINVAL;
1442}
1443
1444/**
1445 * hdd_add_sta_info_sap_get_len - get data length used in
1446 * hdd_add_sta_info_sap()
1447 *
1448 * This function calculates the data length used in hdd_add_sta_info_sap()
1449 *
1450 * Return: total data length used in hdd_add_sta_info_sap()
1451 */
1452static uint32_t hdd_add_sta_info_sap_get_len(void)
1453{
1454 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1455 hdd_add_tx_bitrate_sap_get_len());
1456}
1457
1458/**
1459 * hdd_add_sta_info_sap - add sta signal info attribute
1460 * @skb: pointer to response skb buffer
1461 * @rssi: peer rssi value
1462 * @stainfo: station information
1463 * @idx: attribute type index for nla_next_start()
1464 *
1465 * This function adds sta signal attribute to response skb buffer
1466 *
1467 * Return : 0 on success and errno on failure
1468 */
1469static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1470 struct hdd_cache_sta_info *stainfo, int idx)
1471{
1472 struct nlattr *nla_attr;
1473
1474 nla_attr = nla_nest_start(skb, idx);
1475 if (!nla_attr)
1476 goto fail;
1477
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301478 /* upperlayer expects positive rssi value */
1479 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1481 FL("put fail"));
1482 goto fail;
1483 }
1484 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1486 FL("put fail"));
1487 goto fail;
1488 }
1489
1490 nla_nest_end(skb, nla_attr);
1491 return 0;
1492fail:
1493 return -EINVAL;
1494}
1495
1496/**
1497 * hdd_add_link_standard_info_sap_get_len - get data length used in
1498 * hdd_add_link_standard_info_sap()
1499 *
1500 * This function calculates the data length used in
1501 * hdd_add_link_standard_info_sap()
1502 *
1503 * Return: total data length used in hdd_add_link_standard_info_sap()
1504 */
1505static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1506{
1507 return ((NLA_HDRLEN) +
1508 hdd_add_survey_info_sap_get_len() +
1509 hdd_add_sta_info_sap_get_len() +
1510 (sizeof(uint32_t) + NLA_HDRLEN));
1511}
1512
1513/**
1514 * hdd_add_link_standard_info_sap - add add link info attribut
1515 * @skb: pointer to response skb buffer
1516 * @stainfo: station information
1517 * @idx: attribute type index for nla_next_start()
1518 *
1519 * This function adds link info attribut to response skb buffer
1520 *
1521 * Return : 0 on success and errno on failure
1522 */
1523static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1524 struct hdd_cache_sta_info *stainfo,
1525 int idx)
1526{
1527 struct nlattr *nla_attr;
1528
1529 nla_attr = nla_nest_start(skb, idx);
1530 if (!nla_attr)
1531 goto fail;
1532 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1533 goto fail;
1534 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1535 goto fail;
1536
1537 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1539 FL("put fail"));
1540 goto fail;
1541 }
1542
1543 nla_nest_end(skb, nla_attr);
1544 return 0;
1545fail:
1546 return -EINVAL;
1547}
1548
1549/**
1550 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1551 * hdd_add_ap_standard_info_sap()
1552 * @stainfo: station information
1553 *
1554 * This function calculates the data length used in
1555 * hdd_add_ap_standard_info_sap()
1556 *
1557 * Return: total data length used in hdd_add_ap_standard_info_sap()
1558 */
1559static uint32_t hdd_add_ap_standard_info_sap_get_len(
1560 struct hdd_cache_sta_info *stainfo)
1561{
1562 uint32_t len;
1563
1564 len = NLA_HDRLEN;
1565 if (stainfo->vht_present)
1566 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1567 if (stainfo->ht_present)
1568 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1569
1570 return len;
1571}
1572
1573/**
1574 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1575 * @skb: pointer to response skb buffer
1576 * @stainfo: station information
1577 * @idx: attribute type index for nla_next_start()
1578 *
1579 * This function adds HT and VHT info attributes to response skb buffer
1580 *
1581 * Return : 0 on success and errno on failure
1582 */
1583static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1584 struct hdd_cache_sta_info *stainfo,
1585 int idx)
1586{
1587 struct nlattr *nla_attr;
1588
1589 nla_attr = nla_nest_start(skb, idx);
1590 if (!nla_attr)
1591 goto fail;
1592
1593 if (stainfo->vht_present) {
1594 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1595 sizeof(stainfo->vht_caps),
1596 &stainfo->vht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 if (stainfo->ht_present) {
1603 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1604 sizeof(stainfo->ht_caps),
1605 &stainfo->ht_caps)) {
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1607 FL("put fail"));
1608 goto fail;
1609 }
1610 }
1611 nla_nest_end(skb, nla_attr);
1612 return 0;
1613fail:
1614 return -EINVAL;
1615}
1616
1617/**
1618 * hdd_decode_ch_width - decode channel band width based
1619 * @ch_width: encoded enum value holding channel band width
1620 *
1621 * This function decodes channel band width from the given encoded enum value.
1622 *
1623 * Returns: decoded channel band width.
1624 */
1625static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1626{
1627 switch (ch_width) {
1628 case 0:
1629 return 20;
1630 case 1:
1631 return 40;
1632 case 2:
1633 return 80;
1634 default:
1635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "invalid enum: %d", ch_width);
1637 return 20;
1638 }
1639}
1640
1641/**
1642 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1643 * @hdd_ctx: hdd context
1644 * @adapter: hostapd interface
1645 * @mac_addr: mac address of requested peer
1646 *
1647 * This function collect and indicate the cached(deleted) peer's info
1648 *
1649 * Return: 0 on success, otherwise error value
1650 */
1651static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1652 hdd_adapter_t *adapter,
1653 v_MACADDR_t mac_addr)
1654{
1655 struct hdd_cache_sta_info *stainfo;
1656 struct sk_buff *skb = NULL;
1657 uint32_t nl_buf_len;
1658 uint8_t cw;
1659 ptSapContext sap_ctx;
1660 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1661
1662 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1663 if(sap_ctx == NULL){
1664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 FL("psapCtx is NULL"));
1666 return -ENOENT;
1667 }
1668
1669 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1670 mac_addr.bytes);
1671 if (!stainfo) {
1672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1673 "peer " MAC_ADDRESS_STR " not found",
1674 MAC_ADDR_ARRAY(mac_addr.bytes));
1675 return -EINVAL;
1676 }
1677 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1679 "peer " MAC_ADDRESS_STR " is in connected state",
1680 MAC_ADDR_ARRAY(mac_addr.bytes));
1681 return -EINVAL;
1682 }
1683
1684
1685 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1686 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1687 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1688 (sizeof(cw) + NLA_HDRLEN) +
1689 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1690
1691 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1692 if (!skb) {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1694 return -ENOMEM;
1695 }
1696
1697 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1698 LINK_INFO_STANDARD_NL80211_ATTR)) {
1699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1700 goto fail;
1701 }
1702
1703 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1704 AP_INFO_STANDARD_NL80211_ATTR)) {
1705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1706 goto fail;
1707 }
1708
1709 /* upper layer expects decoded channel BW */
1710 cw = hdd_decode_ch_width(stainfo->ch_width);
1711 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1712 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1714 goto fail;
1715 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301716 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1718 goto fail;
1719 }
1720
1721 vos_mem_zero(stainfo, sizeof(*stainfo));
1722
1723 return cfg80211_vendor_cmd_reply(skb);
1724fail:
1725 if (skb)
1726 kfree_skb(skb);
1727
1728 return -EINVAL;
1729}
1730
1731/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301732 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1733 * @wiphy: corestack handler
1734 * @wdev: wireless device
1735 * @data: data
1736 * @data_len: data length
1737 *
1738 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1739 * Validate cmd attributes and send the station info to upper layers.
1740 *
1741 * Return: Success(0) or reason code for failure
1742 */
1743static int32_t
1744__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1745 struct wireless_dev *wdev,
1746 const void *data,
1747 int data_len)
1748{
1749 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1750 struct net_device *dev = wdev->netdev;
1751 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1752 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1753 int32_t status;
1754
1755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1756 if (VOS_FTM_MODE == hdd_get_conparam()) {
1757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1758 status = -EPERM;
1759 goto out;
1760 }
1761
1762 status = wlan_hdd_validate_context(hdd_ctx);
1763 if (0 != status)
1764 goto out;
1765
1766
1767 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1768 data, data_len, NULL);
1769 if (status) {
1770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1771 goto out;
1772 }
1773
1774 /* Parse and fetch Command Type*/
1775 if (tb[STATION_INFO]) {
1776 status = hdd_get_station_info(hdd_ctx, adapter);
1777 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1778 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301779 } else if (tb[STATION_REMOTE]) {
1780 v_MACADDR_t mac_addr;
1781
1782 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1783 adapter->device_mode != WLAN_HDD_P2P_GO) {
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1785 adapter->device_mode);
1786 status = -EINVAL;
1787 goto out;
1788 }
1789
1790 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1791 VOS_MAC_ADDRESS_LEN);
1792
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1794 MAC_ADDR_ARRAY(mac_addr.bytes));
1795
1796 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1797 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301798 } else {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1800 status = -EINVAL;
1801 goto out;
1802 }
1803 EXIT();
1804out:
1805 return status;
1806}
1807
1808/**
1809 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1810 * @wiphy: corestack handler
1811 * @wdev: wireless device
1812 * @data: data
1813 * @data_len: data length
1814 *
1815 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1816 * Validate cmd attributes and send the station info to upper layers.
1817 *
1818 * Return: Success(0) or reason code for failure
1819 */
1820static int32_t
1821hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1822 struct wireless_dev *wdev,
1823 const void *data,
1824 int data_len)
1825{
1826 int ret;
1827
1828 vos_ssr_protect(__func__);
1829 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1830 vos_ssr_unprotect(__func__);
1831
1832 return ret;
1833}
1834
1835/*
1836 * undef short names defined for get station command
1837 * used by __wlan_hdd_cfg80211_get_station_cmd()
1838 */
1839#undef STATION_INVALID
1840#undef STATION_INFO
1841#undef STATION_ASSOC_FAIL_REASON
1842#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301843
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1845
1846static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1847 struct sk_buff *vendor_event)
1848{
1849 if (nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1851 stats->rate.preamble) ||
1852 nla_put_u8(vendor_event,
1853 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1854 stats->rate.nss) ||
1855 nla_put_u8(vendor_event,
1856 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1857 stats->rate.bw) ||
1858 nla_put_u8(vendor_event,
1859 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1860 stats->rate.rateMcsIdx) ||
1861 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1862 stats->rate.bitrate ) ||
1863 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1864 stats->txMpdu ) ||
1865 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1866 stats->rxMpdu ) ||
1867 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1868 stats->mpduLost ) ||
1869 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1870 stats->retries) ||
1871 nla_put_u32(vendor_event,
1872 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1873 stats->retriesShort ) ||
1874 nla_put_u32(vendor_event,
1875 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1876 stats->retriesLong))
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1880 return FALSE;
1881 }
1882 return TRUE;
1883}
1884
1885static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1886 struct sk_buff *vendor_event)
1887{
1888 u32 i = 0;
1889 struct nlattr *rateInfo;
1890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1891 stats->type) ||
1892 nla_put(vendor_event,
1893 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1894 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1895 nla_put_u32(vendor_event,
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1897 stats->capabilities) ||
1898 nla_put_u32(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1900 stats->numRate))
1901 {
1902 hddLog(VOS_TRACE_LEVEL_ERROR,
1903 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1904 goto error;
1905 }
1906
1907 rateInfo = nla_nest_start(vendor_event,
1908 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rateInfo)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911 for (i = 0; i < stats->numRate; i++)
1912 {
1913 struct nlattr *rates;
1914 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1915 stats->rateStats +
1916 (i * sizeof(tSirWifiRateStat)));
1917 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301918 if(!rates)
1919 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301920
1921 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1922 {
1923 hddLog(VOS_TRACE_LEVEL_ERROR,
1924 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1925 return FALSE;
1926 }
1927 nla_nest_end(vendor_event, rates);
1928 }
1929 nla_nest_end(vendor_event, rateInfo);
1930
1931 return TRUE;
1932error:
1933 return FALSE;
1934}
1935
1936static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1937 struct sk_buff *vendor_event)
1938{
1939 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1940 stats->ac ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1943 stats->txMpdu ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1946 stats->rxMpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1949 stats->txMcast ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1952 stats->rxMcast ) ||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1955 stats->rxAmpdu ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1958 stats->txAmpdu ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1961 stats->mpduLost )||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1964 stats->retries ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1967 stats->retriesShort ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1970 stats->retriesLong ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1973 stats->contentionTimeMin ) ||
1974 nla_put_u32(vendor_event,
1975 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1976 stats->contentionTimeMax ) ||
1977 nla_put_u32(vendor_event,
1978 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1979 stats->contentionTimeAvg ) ||
1980 nla_put_u32(vendor_event,
1981 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1982 stats->contentionNumSamples ))
1983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR,
1985 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1986 return FALSE;
1987 }
1988 return TRUE;
1989}
1990
1991static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1992 struct sk_buff *vendor_event)
1993{
Dino Myclec8f3f332014-07-21 16:48:27 +05301994 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301995 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1996 nla_put(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1998 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1999 nla_put_u32(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2001 stats->state ) ||
2002 nla_put_u32(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2004 stats->roaming ) ||
2005 nla_put_u32(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2007 stats->capabilities ) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2010 strlen(stats->ssid), stats->ssid) ||
2011 nla_put(vendor_event,
2012 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2013 WNI_CFG_BSSID_LEN, stats->bssid) ||
2014 nla_put(vendor_event,
2015 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2016 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2017 nla_put(vendor_event,
2018 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2019 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2020 )
2021 {
2022 hddLog(VOS_TRACE_LEVEL_ERROR,
2023 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2024 return FALSE;
2025 }
2026 return TRUE;
2027}
2028
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2030 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 struct sk_buff *vendor_event)
2032{
2033 int i = 0;
2034 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302035 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2036 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302037 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302038
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039 if (FALSE == put_wifi_interface_info(
2040 &pWifiIfaceStat->info,
2041 vendor_event))
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR,
2044 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2045 return FALSE;
2046
2047 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302048 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2049 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2050 if (NULL == pWifiIfaceStatTL)
2051 {
2052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2053 return FALSE;
2054 }
2055
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302056 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2057 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2058 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2059 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2060
2061 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2062 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2063 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302065
2066 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2067 {
2068 if (VOS_STATUS_SUCCESS ==
2069 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2070 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2071 {
2072 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2073 * obtained from TL structure
2074 */
2075
2076 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2077 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302078 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097
Srinivas Dasari98947432014-11-07 19:41:24 +05302098 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2099 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2100 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2101 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2102 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2103 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2104 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2105 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302106 }
2107 else
2108 {
2109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2110 }
2111
Dino Mycle3b9536d2014-07-09 22:05:24 +05302112 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2113 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2114 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2115 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2116 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2117 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2118 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2119 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2120 }
2121 else
2122 {
2123 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2124 }
2125
2126
Sunil Duttc69bccb2014-05-26 21:30:20 +05302127
2128 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302129 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2130 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2131 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2133 pWifiIfaceStat->beaconRx) ||
2134 nla_put_u32(vendor_event,
2135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2136 pWifiIfaceStat->mgmtRx) ||
2137 nla_put_u32(vendor_event,
2138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2139 pWifiIfaceStat->mgmtActionRx) ||
2140 nla_put_u32(vendor_event,
2141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2142 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302143 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302144 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2145 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302146 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2148 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302149 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2151 pWifiIfaceStat->rssiAck))
2152 {
2153 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302154 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2155 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302156 return FALSE;
2157 }
2158
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302159#ifdef FEATURE_EXT_LL_STAT
2160 /*
2161 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2162 * then host should send Leaky AP stats to upper layer,
2163 * otherwise no need to send these stats.
2164 */
2165 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2166 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2167 )
2168 {
2169 hddLog(VOS_TRACE_LEVEL_INFO,
2170 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2171 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2172 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2173 pWifiIfaceStat->leakyApStat.rx_leak_window,
2174 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2175 if (nla_put_u32(vendor_event,
2176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2177 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2178 nla_put_u32(vendor_event,
2179 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2180 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2181 nla_put_u32(vendor_event,
2182 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2183 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302184 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302185 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2186 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2187 {
2188 hddLog(VOS_TRACE_LEVEL_ERROR,
2189 FL("EXT_LL_STAT put fail"));
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
2193 }
2194#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302195 wmmInfo = nla_nest_start(vendor_event,
2196 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmInfo)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 for (i = 0; i < WIFI_AC_MAX; i++)
2203 {
2204 struct nlattr *wmmStats;
2205 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302206 if(!wmmStats)
2207 {
2208 vos_mem_free(pWifiIfaceStatTL);
2209 return FALSE;
2210 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302211 if (FALSE == put_wifi_wmm_ac_stat(
2212 &pWifiIfaceStat->AccessclassStats[i],
2213 vendor_event))
2214 {
2215 hddLog(VOS_TRACE_LEVEL_ERROR,
2216 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302217 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302218 return FALSE;
2219 }
2220
2221 nla_nest_end(vendor_event, wmmStats);
2222 }
2223 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302224 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 return TRUE;
2226}
2227
2228static tSirWifiInterfaceMode
2229 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2230{
2231 switch (deviceMode)
2232 {
2233 case WLAN_HDD_INFRA_STATION:
2234 return WIFI_INTERFACE_STA;
2235 case WLAN_HDD_SOFTAP:
2236 return WIFI_INTERFACE_SOFTAP;
2237 case WLAN_HDD_P2P_CLIENT:
2238 return WIFI_INTERFACE_P2P_CLIENT;
2239 case WLAN_HDD_P2P_GO:
2240 return WIFI_INTERFACE_P2P_GO;
2241 case WLAN_HDD_IBSS:
2242 return WIFI_INTERFACE_IBSS;
2243 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302244 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302245 }
2246}
2247
2248static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2249 tpSirWifiInterfaceInfo pInfo)
2250{
2251 v_U8_t *staMac = NULL;
2252 hdd_station_ctx_t *pHddStaCtx;
2253 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2254 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2255
2256 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2257
2258 vos_mem_copy(pInfo->macAddr,
2259 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2260
2261 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2262 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2263 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2264 {
2265 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2266 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2267 {
2268 pInfo->state = WIFI_DISCONNECTED;
2269 }
2270 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2271 {
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: Session ID %d, Connection is in progress", __func__,
2274 pAdapter->sessionId);
2275 pInfo->state = WIFI_ASSOCIATING;
2276 }
2277 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2278 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2279 {
2280 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2281 hddLog(VOS_TRACE_LEVEL_ERROR,
2282 "%s: client " MAC_ADDRESS_STR
2283 " is in the middle of WPS/EAPOL exchange.", __func__,
2284 MAC_ADDR_ARRAY(staMac));
2285 pInfo->state = WIFI_AUTHENTICATING;
2286 }
2287 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2288 {
2289 pInfo->state = WIFI_ASSOCIATED;
2290 vos_mem_copy(pInfo->bssid,
2291 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2292 vos_mem_copy(pInfo->ssid,
2293 pHddStaCtx->conn_info.SSID.SSID.ssId,
2294 pHddStaCtx->conn_info.SSID.SSID.length);
2295 //NULL Terminate the string.
2296 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2297 }
2298 }
2299 vos_mem_copy(pInfo->countryStr,
2300 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2301
2302 vos_mem_copy(pInfo->apCountryStr,
2303 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2304
2305 return TRUE;
2306}
2307
2308/*
2309 * hdd_link_layer_process_peer_stats () - This function is called after
2310 * receiving Link Layer Peer statistics from FW.This function converts
2311 * the firmware data to the NL data and sends the same to the kernel/upper
2312 * layers.
2313 */
2314static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2315 v_VOID_t *pData)
2316{
2317 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302318 tpSirWifiPeerStat pWifiPeerStat;
2319 tpSirWifiPeerInfo pWifiPeerInfo;
2320 struct nlattr *peerInfo;
2321 struct sk_buff *vendor_event;
2322 int status, i;
2323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302324 ENTER();
2325
Sunil Duttc69bccb2014-05-26 21:30:20 +05302326 status = wlan_hdd_validate_context(pHddCtx);
2327 if (0 != status)
2328 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 return;
2330 }
2331
2332 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2333
2334 hddLog(VOS_TRACE_LEVEL_INFO,
2335 "LL_STATS_PEER_ALL : numPeers %u",
2336 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302337 /*
2338 * Allocate a size of 4096 for the peer stats comprising
2339 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2340 * sizeof (tSirWifiRateStat).Each field is put with an
2341 * NL attribute.The size of 4096 is considered assuming
2342 * that number of rates shall not exceed beyond 50 with
2343 * the sizeof (tSirWifiRateStat) being 32.
2344 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302345 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2346 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302347 if (!vendor_event)
2348 {
2349 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302350 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302351 __func__);
2352 return;
2353 }
2354 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302355 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2356 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2357 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302358 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2359 pWifiPeerStat->numPeers))
2360 {
2361 hddLog(VOS_TRACE_LEVEL_ERROR,
2362 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2363 kfree_skb(vendor_event);
2364 return;
2365 }
2366
2367 peerInfo = nla_nest_start(vendor_event,
2368 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302369 if(!peerInfo)
2370 {
2371 hddLog(VOS_TRACE_LEVEL_ERROR,
2372 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2373 __func__);
2374 kfree_skb(vendor_event);
2375 return;
2376 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302377
2378 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2379 pWifiPeerStat->peerInfo);
2380
2381 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2382 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302383 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302384 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302386 if(!peers)
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: peer stats put fail",
2390 __func__);
2391 kfree_skb(vendor_event);
2392 return;
2393 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394 if (FALSE == put_wifi_peer_info(
2395 pWifiPeerInfo, vendor_event))
2396 {
2397 hddLog(VOS_TRACE_LEVEL_ERROR,
2398 "%s: put_wifi_peer_info put fail", __func__);
2399 kfree_skb(vendor_event);
2400 return;
2401 }
2402
2403 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2404 pWifiPeerStat->peerInfo +
2405 (i * sizeof(tSirWifiPeerInfo)) +
2406 (numRate * sizeof (tSirWifiRateStat)));
2407 nla_nest_end(vendor_event, peers);
2408 }
2409 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302410 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302412}
2413
2414/*
2415 * hdd_link_layer_process_iface_stats () - This function is called after
2416 * receiving Link Layer Interface statistics from FW.This function converts
2417 * the firmware data to the NL data and sends the same to the kernel/upper
2418 * layers.
2419 */
2420static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2421 v_VOID_t *pData)
2422{
2423 tpSirWifiIfaceStat pWifiIfaceStat;
2424 struct sk_buff *vendor_event;
2425 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2426 int status;
2427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302428 ENTER();
2429
Sunil Duttc69bccb2014-05-26 21:30:20 +05302430 status = wlan_hdd_validate_context(pHddCtx);
2431 if (0 != status)
2432 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302433 return;
2434 }
2435 /*
2436 * Allocate a size of 4096 for the interface stats comprising
2437 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2438 * assuming that all these fit with in the limit.Please take
2439 * a call on the limit based on the data requirements on
2440 * interface statistics.
2441 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302442 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2443 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302444 if (!vendor_event)
2445 {
2446 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302447 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302448 return;
2449 }
2450
2451 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2452
Dino Mycle3b9536d2014-07-09 22:05:24 +05302453
2454 if (FALSE == hdd_get_interface_info( pAdapter,
2455 &pWifiIfaceStat->info))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("hdd_get_interface_info get fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
2463 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2464 vendor_event))
2465 {
2466 hddLog(VOS_TRACE_LEVEL_ERROR,
2467 FL("put_wifi_iface_stats fail") );
2468 kfree_skb(vendor_event);
2469 return;
2470 }
2471
Sunil Duttc69bccb2014-05-26 21:30:20 +05302472 hddLog(VOS_TRACE_LEVEL_INFO,
2473 "WMI_LINK_STATS_IFACE Data");
2474
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302475 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476
2477 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302478}
2479
2480/*
2481 * hdd_link_layer_process_radio_stats () - This function is called after
2482 * receiving Link Layer Radio statistics from FW.This function converts
2483 * the firmware data to the NL data and sends the same to the kernel/upper
2484 * layers.
2485 */
2486static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2487 v_VOID_t *pData)
2488{
2489 int status, i;
2490 tpSirWifiRadioStat pWifiRadioStat;
2491 tpSirWifiChannelStats pWifiChannelStats;
2492 struct sk_buff *vendor_event;
2493 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2494 struct nlattr *chList;
2495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302496 ENTER();
2497
Sunil Duttc69bccb2014-05-26 21:30:20 +05302498 status = wlan_hdd_validate_context(pHddCtx);
2499 if (0 != status)
2500 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302501 return;
2502 }
2503 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2504
2505 hddLog(VOS_TRACE_LEVEL_INFO,
2506 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302507 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302508 " radio is %d onTime is %u "
2509 " txTime is %u rxTime is %u "
2510 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302511 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302512 " onTimePnoScan is %u onTimeHs20 is %u "
2513 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302514 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302515 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2516 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2517 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302518 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302519 pWifiRadioStat->onTimeRoamScan,
2520 pWifiRadioStat->onTimePnoScan,
2521 pWifiRadioStat->onTimeHs20,
2522 pWifiRadioStat->numChannels);
2523 /*
2524 * Allocate a size of 4096 for the Radio stats comprising
2525 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2526 * (tSirWifiChannelStats).Each channel data is put with an
2527 * NL attribute.The size of 4096 is considered assuming that
2528 * number of channels shall not exceed beyond 60 with the
2529 * sizeof (tSirWifiChannelStats) being 24 bytes.
2530 */
2531
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302532 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2533 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302534 if (!vendor_event)
2535 {
2536 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302537 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302538 return;
2539 }
2540
2541 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2543 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2544 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2546 pWifiRadioStat->radio) ||
2547 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302548 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2549 NUM_RADIOS) ||
2550 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2552 pWifiRadioStat->onTime) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2555 pWifiRadioStat->txTime) ||
2556 nla_put_u32(vendor_event,
2557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2558 pWifiRadioStat->rxTime) ||
2559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2561 pWifiRadioStat->onTimeScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2564 pWifiRadioStat->onTimeNbd) ||
2565 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2567 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2570 pWifiRadioStat->onTimeRoamScan) ||
2571 nla_put_u32(vendor_event,
2572 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2573 pWifiRadioStat->onTimePnoScan) ||
2574 nla_put_u32(vendor_event,
2575 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2576 pWifiRadioStat->onTimeHs20) ||
2577 nla_put_u32(vendor_event,
2578 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2579 pWifiRadioStat->numChannels))
2580 {
2581 hddLog(VOS_TRACE_LEVEL_ERROR,
2582 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2583 kfree_skb(vendor_event);
2584 return ;
2585 }
2586
2587 chList = nla_nest_start(vendor_event,
2588 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302589 if(!chList)
2590 {
2591 hddLog(VOS_TRACE_LEVEL_ERROR,
2592 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2593 __func__);
2594 kfree_skb(vendor_event);
2595 return;
2596 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302597 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2598 {
2599 struct nlattr *chInfo;
2600
2601 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2602 pWifiRadioStat->channels +
2603 (i * sizeof(tSirWifiChannelStats)));
2604
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302606 if(!chInfo)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR,
2609 "%s: failed to put chInfo",
2610 __func__);
2611 kfree_skb(vendor_event);
2612 return;
2613 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302614
2615 if (nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2617 pWifiChannelStats->channel.width) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2620 pWifiChannelStats->channel.centerFreq) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2623 pWifiChannelStats->channel.centerFreq0) ||
2624 nla_put_u32(vendor_event,
2625 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2626 pWifiChannelStats->channel.centerFreq1) ||
2627 nla_put_u32(vendor_event,
2628 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2629 pWifiChannelStats->onTime) ||
2630 nla_put_u32(vendor_event,
2631 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2632 pWifiChannelStats->ccaBusyTime))
2633 {
2634 hddLog(VOS_TRACE_LEVEL_ERROR,
2635 FL("cfg80211_vendor_event_alloc failed") );
2636 kfree_skb(vendor_event);
2637 return ;
2638 }
2639 nla_nest_end(vendor_event, chInfo);
2640 }
2641 nla_nest_end(vendor_event, chList);
2642
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302643 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302644
2645 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302646 return;
2647}
2648
2649/*
2650 * hdd_link_layer_stats_ind_callback () - This function is called after
2651 * receiving Link Layer indications from FW.This callback converts the firmware
2652 * data to the NL data and send the same to the kernel/upper layers.
2653 */
2654static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2655 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302656 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302657{
Dino Mycled3d50022014-07-07 12:58:25 +05302658 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2659 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302660 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302661 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302662 int status;
2663
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302664 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302666 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302667 if (0 != status)
2668 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302669 return;
2670 }
2671
Dino Mycled3d50022014-07-07 12:58:25 +05302672 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2673 if (NULL == pAdapter)
2674 {
2675 hddLog(VOS_TRACE_LEVEL_ERROR,
2676 FL(" MAC address %pM does not exist with host"),
2677 macAddr);
2678 return;
2679 }
2680
Sunil Duttc69bccb2014-05-26 21:30:20 +05302681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302682 "%s: Interface: %s LLStats indType: %d", __func__,
2683 pAdapter->dev->name, indType);
2684
Sunil Duttc69bccb2014-05-26 21:30:20 +05302685 switch (indType)
2686 {
2687 case SIR_HAL_LL_STATS_RESULTS_RSP:
2688 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302689 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302690 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2691 "respId = %u, moreResultToFollow = %u",
2692 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2693 macAddr, linkLayerStatsResults->respId,
2694 linkLayerStatsResults->moreResultToFollow);
2695
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302696 spin_lock(&hdd_context_lock);
2697 context = &pHddCtx->ll_stats_context;
2698 /* validate response received from target */
2699 if ((context->request_id != linkLayerStatsResults->respId) ||
2700 !(context->request_bitmap & linkLayerStatsResults->paramId))
2701 {
2702 spin_unlock(&hdd_context_lock);
2703 hddLog(LOGE,
2704 FL("Error : Request id %d response id %d request bitmap 0x%x"
2705 "response bitmap 0x%x"),
2706 context->request_id, linkLayerStatsResults->respId,
2707 context->request_bitmap, linkLayerStatsResults->paramId);
2708 return;
2709 }
2710 spin_unlock(&hdd_context_lock);
2711
Sunil Duttc69bccb2014-05-26 21:30:20 +05302712 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2713 {
2714 hdd_link_layer_process_radio_stats(pAdapter,
2715 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302716 spin_lock(&hdd_context_lock);
2717 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2718 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302719 }
2720 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2721 {
2722 hdd_link_layer_process_iface_stats(pAdapter,
2723 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302724 spin_lock(&hdd_context_lock);
2725 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 }
2728 else if ( linkLayerStatsResults->paramId &
2729 WMI_LINK_STATS_ALL_PEER )
2730 {
2731 hdd_link_layer_process_peer_stats(pAdapter,
2732 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302733 spin_lock(&hdd_context_lock);
2734 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2735 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302736 } /* WMI_LINK_STATS_ALL_PEER */
2737 else
2738 {
2739 hddLog(VOS_TRACE_LEVEL_ERROR,
2740 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2741 }
2742
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302743 spin_lock(&hdd_context_lock);
2744 /* complete response event if all requests are completed */
2745 if (0 == context->request_bitmap)
2746 complete(&context->response_event);
2747 spin_unlock(&hdd_context_lock);
2748
Sunil Duttc69bccb2014-05-26 21:30:20 +05302749 break;
2750 }
2751 default:
2752 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2753 break;
2754 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302755
2756 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302757 return;
2758}
2759
2760const struct
2761nla_policy
2762qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2763{
2764 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2765 { .type = NLA_U32 },
2766 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2767 { .type = NLA_U32 },
2768};
2769
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302770static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2771 struct wireless_dev *wdev,
2772 const void *data,
2773 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302774{
2775 int status;
2776 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302777 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 struct net_device *dev = wdev->netdev;
2779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2780 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2781
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302782 ENTER();
2783
Sunil Duttc69bccb2014-05-26 21:30:20 +05302784 status = wlan_hdd_validate_context(pHddCtx);
2785 if (0 != status)
2786 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302787 return -EINVAL;
2788 }
2789
2790 if (NULL == pAdapter)
2791 {
2792 hddLog(VOS_TRACE_LEVEL_ERROR,
2793 FL("HDD adapter is Null"));
2794 return -ENODEV;
2795 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302796 /* check the LLStats Capability */
2797 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2798 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2799 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302800 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302801 FL("Link Layer Statistics not supported by Firmware"));
2802 return -EINVAL;
2803 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302804
2805 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2806 (struct nlattr *)data,
2807 data_len, qca_wlan_vendor_ll_set_policy))
2808 {
2809 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2810 return -EINVAL;
2811 }
2812 if (!tb_vendor
2813 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2814 {
2815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2816 return -EINVAL;
2817 }
2818 if (!tb_vendor[
2819 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2820 {
2821 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2822 return -EINVAL;
2823 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302824 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302825 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302826
Dino Mycledf0a5d92014-07-04 09:41:55 +05302827 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828 nla_get_u32(
2829 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2830
Dino Mycledf0a5d92014-07-04 09:41:55 +05302831 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302832 nla_get_u32(
2833 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2834
Dino Mycled3d50022014-07-07 12:58:25 +05302835 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2836 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302837
2838
2839 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302840 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2841 "Statistics Gathering = %d ",
2842 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2843 linkLayerStatsSetReq.mpduSizeThreshold,
2844 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302845
2846 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2847 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302848 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853
2854 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302855
Sunil Duttc69bccb2014-05-26 21:30:20 +05302856 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302857 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 {
2859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2860 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302861 return -EINVAL;
2862 }
2863
2864 pAdapter->isLinkLayerStatsSet = 1;
2865
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302866 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302867 return 0;
2868}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302869static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2870 struct wireless_dev *wdev,
2871 const void *data,
2872 int data_len)
2873{
2874 int ret = 0;
2875
2876 vos_ssr_protect(__func__);
2877 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2878 vos_ssr_unprotect(__func__);
2879
2880 return ret;
2881}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302882
2883const struct
2884nla_policy
2885qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2886{
2887 /* Unsigned 32bit value provided by the caller issuing the GET stats
2888 * command. When reporting
2889 * the stats results, the driver uses the same value to indicate
2890 * which GET request the results
2891 * correspond to.
2892 */
2893 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2894
2895 /* Unsigned 32bit value . bit mask to identify what statistics are
2896 requested for retrieval */
2897 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2898};
2899
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302900static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2901 struct wireless_dev *wdev,
2902 const void *data,
2903 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302905 unsigned long rc;
2906 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302907 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2908 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302909 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302910 struct net_device *dev = wdev->netdev;
2911 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302912 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302913 int status;
2914
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302915 ENTER();
2916
Sunil Duttc69bccb2014-05-26 21:30:20 +05302917 status = wlan_hdd_validate_context(pHddCtx);
2918 if (0 != status)
2919 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302920 return -EINVAL ;
2921 }
2922
2923 if (NULL == pAdapter)
2924 {
2925 hddLog(VOS_TRACE_LEVEL_FATAL,
2926 "%s: HDD adapter is Null", __func__);
2927 return -ENODEV;
2928 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302929
2930 if (pHddStaCtx == NULL)
2931 {
2932 hddLog(VOS_TRACE_LEVEL_FATAL,
2933 "%s: HddStaCtx is Null", __func__);
2934 return -ENODEV;
2935 }
2936
Dino Mycledf0a5d92014-07-04 09:41:55 +05302937 /* check the LLStats Capability */
2938 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2939 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2940 {
2941 hddLog(VOS_TRACE_LEVEL_ERROR,
2942 FL("Link Layer Statistics not supported by Firmware"));
2943 return -EINVAL;
2944 }
2945
Sunil Duttc69bccb2014-05-26 21:30:20 +05302946
2947 if (!pAdapter->isLinkLayerStatsSet)
2948 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302949 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302950 "%s: isLinkLayerStatsSet : %d",
2951 __func__, pAdapter->isLinkLayerStatsSet);
2952 return -EINVAL;
2953 }
2954
Mukul Sharma10313ba2015-07-29 19:14:39 +05302955 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2956 {
2957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2958 "%s: Roaming in progress, so unable to proceed this request", __func__);
2959 return -EBUSY;
2960 }
2961
Sunil Duttc69bccb2014-05-26 21:30:20 +05302962 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2963 (struct nlattr *)data,
2964 data_len, qca_wlan_vendor_ll_get_policy))
2965 {
2966 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2967 return -EINVAL;
2968 }
2969
2970 if (!tb_vendor
2971 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2972 {
2973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2974 return -EINVAL;
2975 }
2976
2977 if (!tb_vendor
2978 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2979 {
2980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2981 return -EINVAL;
2982 }
2983
Sunil Duttc69bccb2014-05-26 21:30:20 +05302984
Dino Mycledf0a5d92014-07-04 09:41:55 +05302985 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302986 nla_get_u32( tb_vendor[
2987 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302988 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302989 nla_get_u32( tb_vendor[
2990 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2991
Dino Mycled3d50022014-07-07 12:58:25 +05302992 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2993 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302994
2995 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302996 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2997 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302998 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302999
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303000 spin_lock(&hdd_context_lock);
3001 context = &pHddCtx->ll_stats_context;
3002 context->request_id = linkLayerStatsGetReq.reqId;
3003 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3004 INIT_COMPLETION(context->response_event);
3005 spin_unlock(&hdd_context_lock);
3006
Sunil Duttc69bccb2014-05-26 21:30:20 +05303007 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303008 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3011 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 return -EINVAL;
3013 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303014
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303015 rc = wait_for_completion_timeout(&context->response_event,
3016 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3017 if (!rc)
3018 {
3019 hddLog(LOGE,
3020 FL("Target response timed out request id %d request bitmap 0x%x"),
3021 context->request_id, context->request_bitmap);
3022 return -ETIMEDOUT;
3023 }
3024
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303025 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303026 return 0;
3027}
3028
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303029static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3030 struct wireless_dev *wdev,
3031 const void *data,
3032 int data_len)
3033{
3034 int ret = 0;
3035
3036 vos_ssr_protect(__func__);
3037 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3038 vos_ssr_unprotect(__func__);
3039
3040 return ret;
3041}
3042
Sunil Duttc69bccb2014-05-26 21:30:20 +05303043const struct
3044nla_policy
3045qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3046{
3047 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3048 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3049 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3050 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3051};
3052
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303053static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3054 struct wireless_dev *wdev,
3055 const void *data,
3056 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303057{
3058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3059 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303060 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303061 struct net_device *dev = wdev->netdev;
3062 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3063 u32 statsClearReqMask;
3064 u8 stopReq;
3065 int status;
3066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303067 ENTER();
3068
Sunil Duttc69bccb2014-05-26 21:30:20 +05303069 status = wlan_hdd_validate_context(pHddCtx);
3070 if (0 != status)
3071 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303072 return -EINVAL;
3073 }
3074
3075 if (NULL == pAdapter)
3076 {
3077 hddLog(VOS_TRACE_LEVEL_FATAL,
3078 "%s: HDD adapter is Null", __func__);
3079 return -ENODEV;
3080 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303081 /* check the LLStats Capability */
3082 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3083 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3084 {
3085 hddLog(VOS_TRACE_LEVEL_ERROR,
3086 FL("Enable LLStats Capability"));
3087 return -EINVAL;
3088 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303089
3090 if (!pAdapter->isLinkLayerStatsSet)
3091 {
3092 hddLog(VOS_TRACE_LEVEL_FATAL,
3093 "%s: isLinkLayerStatsSet : %d",
3094 __func__, pAdapter->isLinkLayerStatsSet);
3095 return -EINVAL;
3096 }
3097
3098 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3099 (struct nlattr *)data,
3100 data_len, qca_wlan_vendor_ll_clr_policy))
3101 {
3102 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3103 return -EINVAL;
3104 }
3105
3106 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3107
3108 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3111 return -EINVAL;
3112
3113 }
3114
Sunil Duttc69bccb2014-05-26 21:30:20 +05303115
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117 nla_get_u32(
3118 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3119
Dino Mycledf0a5d92014-07-04 09:41:55 +05303120 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303121 nla_get_u8(
3122 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3123
3124 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303125 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303126
Dino Mycled3d50022014-07-07 12:58:25 +05303127 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3128 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303129
3130 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303131 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3132 "statsClearReqMask = 0x%X, stopReq = %d",
3133 linkLayerStatsClearReq.reqId,
3134 linkLayerStatsClearReq.macAddr,
3135 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303136 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303137
3138 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303139 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303140 {
3141 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303142 hdd_station_ctx_t *pHddStaCtx;
3143
3144 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3145 if (VOS_STATUS_SUCCESS !=
3146 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3147 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3148 {
3149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3150 "WLANTL_ClearInterfaceStats Failed", __func__);
3151 return -EINVAL;
3152 }
3153 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3154 (statsClearReqMask & WIFI_STATS_IFACE)) {
3155 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3156 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3157 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3158 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3159 }
3160
Sunil Duttc69bccb2014-05-26 21:30:20 +05303161 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3162 2 * sizeof(u32) +
3163 NLMSG_HDRLEN);
3164
3165 if (temp_skbuff != NULL)
3166 {
3167
3168 if (nla_put_u32(temp_skbuff,
3169 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3170 statsClearReqMask) ||
3171 nla_put_u32(temp_skbuff,
3172 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3173 stopReq))
3174 {
3175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3176 kfree_skb(temp_skbuff);
3177 return -EINVAL;
3178 }
3179 /* If the ask is to stop the stats collection as part of clear
3180 * (stopReq = 1) , ensure that no further requests of get
3181 * go to the firmware by having isLinkLayerStatsSet set to 0.
3182 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303183 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303184 * case the firmware is just asked to clear the statistics.
3185 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303186 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303187 pAdapter->isLinkLayerStatsSet = 0;
3188 return cfg80211_vendor_cmd_reply(temp_skbuff);
3189 }
3190 return -ENOMEM;
3191 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303192
3193 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303194 return -EINVAL;
3195}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303196static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3197 struct wireless_dev *wdev,
3198 const void *data,
3199 int data_len)
3200{
3201 int ret = 0;
3202
3203 vos_ssr_protect(__func__);
3204 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3205 vos_ssr_unprotect(__func__);
3206
3207 return ret;
3208
3209
3210}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303211#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3212
Dino Mycle6fb96c12014-06-10 11:52:40 +05303213#ifdef WLAN_FEATURE_EXTSCAN
3214static const struct nla_policy
3215wlan_hdd_extscan_config_policy
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3217{
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3219 { .type = NLA_U32 },
3220 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3221 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3223 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3226 { .type = NLA_U32 },
3227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3229
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3231 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3233 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3234 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3236 { .type = NLA_U32 },
3237 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3238 { .type = NLA_U32 },
3239 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3240 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3242 { .type = NLA_U32 },
3243 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3244 { .type = NLA_U32 },
3245 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3246 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3248 { .type = NLA_U8 },
3249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303250 { .type = NLA_U8 },
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3252 { .type = NLA_U8 },
3253 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3254 { .type = NLA_U8 },
3255
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3257 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3259 .type = NLA_UNSPEC,
3260 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303261 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3262 { .type = NLA_S32 },
3263 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3264 { .type = NLA_S32 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3266 { .type = NLA_U32 },
3267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3268 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3270 { .type = NLA_U32 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3272 { .type = NLA_BINARY,
3273 .len = IEEE80211_MAX_SSID_LEN + 1 },
3274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303275 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3277 { .type = NLA_U32 },
3278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3279 { .type = NLA_U8 },
3280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3281 { .type = NLA_S32 },
3282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3283 { .type = NLA_S32 },
3284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3285 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303286};
3287
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303288/**
3289 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3290 * @ctx: hdd global context
3291 * @data: capabilities data
3292 *
3293 * Return: none
3294 */
3295static void
3296wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303297{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303298 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303300 tSirEXTScanCapabilitiesEvent *data =
3301 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303303 ENTER();
3304
3305 if (wlan_hdd_validate_context(pHddCtx))
3306 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 return;
3308 }
3309
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303310 if (!pMsg)
3311 {
3312 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3313 return;
3314 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303316 vos_spin_lock_acquire(&hdd_context_lock);
3317
3318 context = &pHddCtx->ext_scan_context;
3319 /* validate response received from target*/
3320 if (context->request_id != data->requestId)
3321 {
3322 vos_spin_lock_release(&hdd_context_lock);
3323 hddLog(LOGE,
3324 FL("Target response id did not match: request_id %d resposne_id %d"),
3325 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303328 else
3329 {
3330 context->capability_response = *data;
3331 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303332 }
3333
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303334 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335
Dino Mycle6fb96c12014-06-10 11:52:40 +05303336 return;
3337}
3338
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303339/*
3340 * define short names for the global vendor params
3341 * used by wlan_hdd_send_ext_scan_capability()
3342 */
3343#define PARAM_REQUEST_ID \
3344 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3345#define PARAM_STATUS \
3346 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3347#define MAX_SCAN_CACHE_SIZE \
3348 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3349#define MAX_SCAN_BUCKETS \
3350 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3351#define MAX_AP_CACHE_PER_SCAN \
3352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3353#define MAX_RSSI_SAMPLE_SIZE \
3354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3355#define MAX_SCAN_RPT_THRHOLD \
3356 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3357#define MAX_HOTLIST_BSSIDS \
3358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3359#define MAX_BSSID_HISTORY_ENTRIES \
3360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3361#define MAX_HOTLIST_SSIDS \
3362 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303363#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3364 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303365
3366static int wlan_hdd_send_ext_scan_capability(void *ctx)
3367{
3368 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3369 struct sk_buff *skb = NULL;
3370 int ret;
3371 tSirEXTScanCapabilitiesEvent *data;
3372 tANI_U32 nl_buf_len;
3373
3374 ret = wlan_hdd_validate_context(pHddCtx);
3375 if (0 != ret)
3376 {
3377 return ret;
3378 }
3379
3380 data = &(pHddCtx->ext_scan_context.capability_response);
3381
3382 nl_buf_len = NLMSG_HDRLEN;
3383 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3384 (sizeof(data->status) + NLA_HDRLEN) +
3385 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3386 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3387 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3388 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3389 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3390 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3391 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3392 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3393
3394 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3395
3396 if (!skb)
3397 {
3398 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3399 return -ENOMEM;
3400 }
3401
3402 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3403 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3404 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3405 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3406 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3407 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3408 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3409 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3410
3411 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3412 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3413 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3414 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3415 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3416 data->maxApPerScan) ||
3417 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3418 data->maxRssiSampleSize) ||
3419 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3420 data->maxScanReportingThreshold) ||
3421 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3422 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3423 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303424 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3425 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303426 {
3427 hddLog(LOGE, FL("nla put fail"));
3428 goto nla_put_failure;
3429 }
3430
3431 cfg80211_vendor_cmd_reply(skb);
3432 return 0;
3433
3434nla_put_failure:
3435 kfree_skb(skb);
3436 return -EINVAL;;
3437}
3438
3439/*
3440 * done with short names for the global vendor params
3441 * used by wlan_hdd_send_ext_scan_capability()
3442 */
3443#undef PARAM_REQUEST_ID
3444#undef PARAM_STATUS
3445#undef MAX_SCAN_CACHE_SIZE
3446#undef MAX_SCAN_BUCKETS
3447#undef MAX_AP_CACHE_PER_SCAN
3448#undef MAX_RSSI_SAMPLE_SIZE
3449#undef MAX_SCAN_RPT_THRHOLD
3450#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303451#undef MAX_BSSID_HISTORY_ENTRIES
3452#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
3454static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3455{
3456 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3457 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303459 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303461 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303463 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303464 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303466 if (!pMsg)
3467 {
3468 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 return;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3473 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3474
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303475 context = &pHddCtx->ext_scan_context;
3476 spin_lock(&hdd_context_lock);
3477 if (context->request_id == pData->requestId) {
3478 context->response_status = pData->status ? -EINVAL : 0;
3479 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303481 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482
3483 /*
3484 * Store the Request ID for comparing with the requestID obtained
3485 * in other requests.HDD shall return a failure is the extscan_stop
3486 * request is issued with a different requestId as that of the
3487 * extscan_start request. Also, This requestId shall be used while
3488 * indicating the full scan results to the upper layers.
3489 * The requestId is stored with the assumption that the firmware
3490 * shall return the ext scan start request's requestId in ext scan
3491 * start response.
3492 */
3493 if (pData->status == 0)
3494 pMac->sme.extScanStartReqId = pData->requestId;
3495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303496 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303498}
3499
3500
3501static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3502{
3503 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3504 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303505 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303507 ENTER();
3508
3509 if (wlan_hdd_validate_context(pHddCtx)){
3510 return;
3511 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 if (!pMsg)
3514 {
3515 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 return;
3517 }
3518
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3520 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303521
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303522 context = &pHddCtx->ext_scan_context;
3523 spin_lock(&hdd_context_lock);
3524 if (context->request_id == pData->requestId) {
3525 context->response_status = pData->status ? -EINVAL : 0;
3526 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303528 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303530 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532}
3533
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3535 void *pMsg)
3536{
3537 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538 tpSirEXTScanSetBssidHotListRspParams pData =
3539 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303540 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303542 ENTER();
3543
3544 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545 return;
3546 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303547
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303548 if (!pMsg)
3549 {
3550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3551 return;
3552 }
3553
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3555 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303556
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303557 context = &pHddCtx->ext_scan_context;
3558 spin_lock(&hdd_context_lock);
3559 if (context->request_id == pData->requestId) {
3560 context->response_status = pData->status ? -EINVAL : 0;
3561 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303563 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303565 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303566 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567}
3568
3569static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3570 void *pMsg)
3571{
3572 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 tpSirEXTScanResetBssidHotlistRspParams pData =
3574 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303575 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303577 ENTER();
3578
3579 if (wlan_hdd_validate_context(pHddCtx)) {
3580 return;
3581 }
3582 if (!pMsg)
3583 {
3584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 return;
3586 }
3587
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3589 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303591 context = &pHddCtx->ext_scan_context;
3592 spin_lock(&hdd_context_lock);
3593 if (context->request_id == pData->requestId) {
3594 context->response_status = pData->status ? -EINVAL : 0;
3595 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303597 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303599 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601}
3602
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3604 void *pMsg)
3605{
3606 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3607 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303608 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609 tANI_S32 totalResults;
3610 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303611 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3612 struct hdd_ext_scan_context *context;
3613 bool ignore_cached_results = false;
3614 tExtscanCachedScanResult *result;
3615 struct nlattr *nla_results;
3616 tANI_U16 ieLength= 0;
3617 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303619 ENTER();
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303623
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303624 if (!pMsg)
3625 {
3626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3627 return;
3628 }
3629
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303630 spin_lock(&hdd_context_lock);
3631 context = &pHddCtx->ext_scan_context;
3632 ignore_cached_results = context->ignore_cached_results;
3633 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 if (ignore_cached_results) {
3636 hddLog(LOGE,
3637 FL("Ignore the cached results received after timeout"));
3638 return;
3639 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3642 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303643
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303644 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3647 scan_id_index++) {
3648 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303649
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303650 totalResults = result->num_results;
3651 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3652 result->scan_id, result->flags, totalResults);
3653 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303654
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303655 do{
3656 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3657 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3658 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303660 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3661 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3662
3663 if (!skb) {
3664 hddLog(VOS_TRACE_LEVEL_ERROR,
3665 FL("cfg80211_vendor_event_alloc failed"));
3666 return;
3667 }
3668
3669 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3670
3671 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3672 pData->requestId) ||
3673 nla_put_u32(skb,
3674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3675 resultsPerEvent)) {
3676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3677 goto fail;
3678 }
3679 if (nla_put_u8(skb,
3680 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3681 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303682 {
3683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3684 goto fail;
3685 }
3686
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303687 if (nla_put_u32(skb,
3688 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3689 result->scan_id)) {
3690 hddLog(LOGE, FL("put fail"));
3691 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303693
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303694 nla_results = nla_nest_start(skb,
3695 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3696 if (!nla_results)
3697 goto fail;
3698
3699 if (resultsPerEvent) {
3700 struct nlattr *aps;
3701 struct nlattr *nla_result;
3702
3703 nla_result = nla_nest_start(skb, scan_id_index);
3704 if(!nla_result)
3705 goto fail;
3706
3707 if (nla_put_u32(skb,
3708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3709 result->scan_id) ||
3710 nla_put_u32(skb,
3711 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3712 result->flags) ||
3713 nla_put_u32(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3715 totalResults)) {
3716 hddLog(LOGE, FL("put fail"));
3717 goto fail;
3718 }
3719
3720 aps = nla_nest_start(skb,
3721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3722 if (!aps)
3723 {
3724 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3725 goto fail;
3726 }
3727
3728 head_ptr = (tpSirWifiScanResult) &(result->ap);
3729
3730 for (j = 0; j < resultsPerEvent; j++, i++) {
3731 struct nlattr *ap;
3732 pSirWifiScanResult = head_ptr + i;
3733
3734 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303735 * Firmware returns timestamp from extscan_start till
3736 * BSSID was cached (in micro seconds). Add this with
3737 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303738 * to derive the time since boot when the
3739 * BSSID was cached.
3740 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303741 pSirWifiScanResult->ts +=
3742 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303743 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3744 "Ssid (%s)"
3745 "Bssid: %pM "
3746 "Channel (%u)"
3747 "Rssi (%d)"
3748 "RTT (%u)"
3749 "RTT_SD (%u)"
3750 "Beacon Period %u"
3751 "Capability 0x%x "
3752 "Ie length %d",
3753 i,
3754 pSirWifiScanResult->ts,
3755 pSirWifiScanResult->ssid,
3756 pSirWifiScanResult->bssid,
3757 pSirWifiScanResult->channel,
3758 pSirWifiScanResult->rssi,
3759 pSirWifiScanResult->rtt,
3760 pSirWifiScanResult->rtt_sd,
3761 pSirWifiScanResult->beaconPeriod,
3762 pSirWifiScanResult->capability,
3763 ieLength);
3764
3765 ap = nla_nest_start(skb, j + 1);
3766 if (!ap)
3767 {
3768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3769 goto fail;
3770 }
3771
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303772 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3774 pSirWifiScanResult->ts) )
3775 {
3776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3777 goto fail;
3778 }
3779 if (nla_put(skb,
3780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3781 sizeof(pSirWifiScanResult->ssid),
3782 pSirWifiScanResult->ssid) )
3783 {
3784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3785 goto fail;
3786 }
3787 if (nla_put(skb,
3788 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3789 sizeof(pSirWifiScanResult->bssid),
3790 pSirWifiScanResult->bssid) )
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3793 goto fail;
3794 }
3795 if (nla_put_u32(skb,
3796 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3797 pSirWifiScanResult->channel) )
3798 {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3800 goto fail;
3801 }
3802 if (nla_put_s32(skb,
3803 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3804 pSirWifiScanResult->rssi) )
3805 {
3806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3807 goto fail;
3808 }
3809 if (nla_put_u32(skb,
3810 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3811 pSirWifiScanResult->rtt) )
3812 {
3813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3814 goto fail;
3815 }
3816 if (nla_put_u32(skb,
3817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3818 pSirWifiScanResult->rtt_sd))
3819 {
3820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3821 goto fail;
3822 }
3823 if (nla_put_u32(skb,
3824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3825 pSirWifiScanResult->beaconPeriod))
3826 {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3828 goto fail;
3829 }
3830 if (nla_put_u32(skb,
3831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3832 pSirWifiScanResult->capability))
3833 {
3834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3835 goto fail;
3836 }
3837 if (nla_put_u32(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3839 ieLength))
3840 {
3841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3842 goto fail;
3843 }
3844
3845 if (ieLength)
3846 if (nla_put(skb,
3847 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3848 ieLength, ie)) {
3849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3850 goto fail;
3851 }
3852
3853 nla_nest_end(skb, ap);
3854 }
3855 nla_nest_end(skb, aps);
3856 nla_nest_end(skb, nla_result);
3857 }
3858
3859 nla_nest_end(skb, nla_results);
3860
3861 cfg80211_vendor_cmd_reply(skb);
3862
3863 } while (totalResults > 0);
3864 }
3865
3866 if (!pData->moreData) {
3867 spin_lock(&hdd_context_lock);
3868 context->response_status = 0;
3869 complete(&context->response_event);
3870 spin_unlock(&hdd_context_lock);
3871 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303873 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303874 return;
3875fail:
3876 kfree_skb(skb);
3877 return;
3878}
3879
3880static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3881 void *pMsg)
3882{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303883 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303884 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3885 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303886 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303888 ENTER();
3889
3890 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303891 hddLog(LOGE,
3892 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303893 return;
3894 }
3895 if (!pMsg)
3896 {
3897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303898 return;
3899 }
3900
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303901 if (pData->bss_found)
3902 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3903 else
3904 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3905
Dino Mycle6fb96c12014-06-10 11:52:40 +05303906 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3908 NULL,
3909#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303910 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303911 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303912
3913 if (!skb) {
3914 hddLog(VOS_TRACE_LEVEL_ERROR,
3915 FL("cfg80211_vendor_event_alloc failed"));
3916 return;
3917 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303919 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3920 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3921 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3922 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3923
3924 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3926 "Ssid (%s) "
3927 "Bssid (" MAC_ADDRESS_STR ") "
3928 "Channel (%u) "
3929 "Rssi (%d) "
3930 "RTT (%u) "
3931 "RTT_SD (%u) ",
3932 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303933 pData->bssHotlist[i].ts,
3934 pData->bssHotlist[i].ssid,
3935 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3936 pData->bssHotlist[i].channel,
3937 pData->bssHotlist[i].rssi,
3938 pData->bssHotlist[i].rtt,
3939 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 }
3941
3942 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3943 pData->requestId) ||
3944 nla_put_u32(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303946 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303947 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3948 goto fail;
3949 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303950 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303951 struct nlattr *aps;
3952
3953 aps = nla_nest_start(skb,
3954 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3955 if (!aps)
3956 goto fail;
3957
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 struct nlattr *ap;
3960
3961 ap = nla_nest_start(skb, i + 1);
3962 if (!ap)
3963 goto fail;
3964
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303965 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303967 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303968 nla_put(skb,
3969 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303970 sizeof(pData->bssHotlist[i].ssid),
3971 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303972 nla_put(skb,
3973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303974 sizeof(pData->bssHotlist[i].bssid),
3975 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 nla_put_s32(skb,
3980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303981 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 nla_put_u32(skb,
3983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303984 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303987 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303988 goto fail;
3989
3990 nla_nest_end(skb, ap);
3991 }
3992 nla_nest_end(skb, aps);
3993
3994 if (nla_put_u8(skb,
3995 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3996 pData->moreData))
3997 goto fail;
3998 }
3999
4000 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304001 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002 return;
4003
4004fail:
4005 kfree_skb(skb);
4006 return;
4007
4008}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304009
4010static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4011 void *pMsg)
4012{
4013 struct sk_buff *skb;
4014 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4015 tpSirWifiFullScanResultEvent pData =
4016 (tpSirWifiFullScanResultEvent) (pMsg);
4017
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304018 ENTER();
4019
4020 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304021 hddLog(LOGE,
4022 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304023 return;
4024 }
4025 if (!pMsg)
4026 {
4027 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304028 return;
4029 }
4030
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304031 /*
4032 * If the full scan result including IE data exceeds NL 4K size
4033 * limitation, drop that beacon/probe rsp frame.
4034 */
4035 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4036 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4037 return;
4038 }
4039
Dino Mycle6fb96c12014-06-10 11:52:40 +05304040 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4042 NULL,
4043#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304044 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4045 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4046 GFP_KERNEL);
4047
4048 if (!skb) {
4049 hddLog(VOS_TRACE_LEVEL_ERROR,
4050 FL("cfg80211_vendor_event_alloc failed"));
4051 return;
4052 }
4053
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4055 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4056 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4057 "Ssid (%s)"
4058 "Bssid (" MAC_ADDRESS_STR ")"
4059 "Channel (%u)"
4060 "Rssi (%d)"
4061 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 "RTT_SD (%u)"
4063 "Bcn Period %d"
4064 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304065 pData->ap.ts,
4066 pData->ap.ssid,
4067 MAC_ADDR_ARRAY(pData->ap.bssid),
4068 pData->ap.channel,
4069 pData->ap.rssi,
4070 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304071 pData->ap.rtt_sd,
4072 pData->ap.beaconPeriod,
4073 pData->ap.capability);
4074
Dino Mycle6fb96c12014-06-10 11:52:40 +05304075 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4076 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4077 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304078 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4080 pData->ap.ts) ||
4081 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4082 sizeof(pData->ap.ssid),
4083 pData->ap.ssid) ||
4084 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4085 WNI_CFG_BSSID_LEN,
4086 pData->ap.bssid) ||
4087 nla_put_u32(skb,
4088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4089 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304090 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304091 pData->ap.rssi) ||
4092 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4093 pData->ap.rtt) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4096 pData->ap.rtt_sd) ||
4097 nla_put_u16(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4099 pData->ap.beaconPeriod) ||
4100 nla_put_u16(skb,
4101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4102 pData->ap.capability) ||
4103 nla_put_u32(skb,
4104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304105 pData->ieLength) ||
4106 nla_put_u8(skb,
4107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4108 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304113
4114 if (pData->ieLength) {
4115 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4116 pData->ieLength,
4117 pData->ie))
4118 {
4119 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4120 goto nla_put_failure;
4121 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304122 }
4123
4124 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304125 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304126 return;
4127
4128nla_put_failure:
4129 kfree_skb(skb);
4130 return;
4131}
4132
4133static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4134 void *pMsg)
4135{
4136 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4137 struct sk_buff *skb = NULL;
4138 tpSirEXTScanResultsAvailableIndParams pData =
4139 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304141 ENTER();
4142
4143 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304144 hddLog(LOGE,
4145 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304146 return;
4147 }
4148 if (!pMsg)
4149 {
4150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304151 return;
4152 }
4153
4154 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4156 NULL,
4157#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4159 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4160 GFP_KERNEL);
4161
4162 if (!skb) {
4163 hddLog(VOS_TRACE_LEVEL_ERROR,
4164 FL("cfg80211_vendor_event_alloc failed"));
4165 return;
4166 }
4167
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4169 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4170 pData->numResultsAvailable);
4171 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4172 pData->requestId) ||
4173 nla_put_u32(skb,
4174 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4175 pData->numResultsAvailable)) {
4176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4177 goto nla_put_failure;
4178 }
4179
4180 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304181 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 return;
4183
4184nla_put_failure:
4185 kfree_skb(skb);
4186 return;
4187}
4188
4189static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4190{
4191 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4192 struct sk_buff *skb = NULL;
4193 tpSirEXTScanProgressIndParams pData =
4194 (tpSirEXTScanProgressIndParams) pMsg;
4195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
4198 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304199 hddLog(LOGE,
4200 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304201 return;
4202 }
4203 if (!pMsg)
4204 {
4205 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 return;
4207 }
4208
4209 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4211 NULL,
4212#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4214 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4215 GFP_KERNEL);
4216
4217 if (!skb) {
4218 hddLog(VOS_TRACE_LEVEL_ERROR,
4219 FL("cfg80211_vendor_event_alloc failed"));
4220 return;
4221 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4224 pData->extScanEventType);
4225 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4226 pData->status);
4227
4228 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4229 pData->extScanEventType) ||
4230 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304231 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4232 pData->requestId) ||
4233 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4235 pData->status)) {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4237 goto nla_put_failure;
4238 }
4239
4240 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304241 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 return;
4243
4244nla_put_failure:
4245 kfree_skb(skb);
4246 return;
4247}
4248
4249void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4250 void *pMsg)
4251{
4252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304254 ENTER();
4255
Dino Mycle6fb96c12014-06-10 11:52:40 +05304256 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 return;
4258 }
4259
4260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4261
4262
4263 switch(evType) {
4264 case SIR_HAL_EXTSCAN_START_RSP:
4265 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4266 break;
4267
4268 case SIR_HAL_EXTSCAN_STOP_RSP:
4269 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4270 break;
4271 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4272 /* There is no need to send this response to upper layer
4273 Just log the message */
4274 hddLog(VOS_TRACE_LEVEL_INFO,
4275 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4276 break;
4277 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4278 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4279 break;
4280
4281 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4282 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4283 break;
4284
Dino Mycle6fb96c12014-06-10 11:52:40 +05304285 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304286 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304287 break;
4288 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4289 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4290 break;
4291 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4292 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4293 break;
4294 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4295 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4296 break;
4297 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4298 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4299 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4301 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4302 break;
4303 default:
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4305 break;
4306 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304307 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304308}
4309
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304310static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4311 struct wireless_dev *wdev,
4312 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313{
Dino Myclee8843b32014-07-04 14:21:45 +05304314 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315 struct net_device *dev = wdev->netdev;
4316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4317 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4318 struct nlattr
4319 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4320 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304321 struct hdd_ext_scan_context *context;
4322 unsigned long rc;
4323 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304325 ENTER();
4326
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327 status = wlan_hdd_validate_context(pHddCtx);
4328 if (0 != status)
4329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 return -EINVAL;
4331 }
Dino Myclee8843b32014-07-04 14:21:45 +05304332 /* check the EXTScan Capability */
4333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304336 {
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 FL("EXTScan not enabled/supported by Firmware"));
4339 return -EINVAL;
4340 }
4341
Dino Mycle6fb96c12014-06-10 11:52:40 +05304342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4343 data, dataLen,
4344 wlan_hdd_extscan_config_policy)) {
4345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4346 return -EINVAL;
4347 }
4348
4349 /* Parse and fetch request Id */
4350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4352 return -EINVAL;
4353 }
4354
Dino Myclee8843b32014-07-04 14:21:45 +05304355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 reqMsg.sessionId = pAdapter->sessionId;
4360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304361
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304362 vos_spin_lock_acquire(&hdd_context_lock);
4363 context = &pHddCtx->ext_scan_context;
4364 context->request_id = reqMsg.requestId;
4365 INIT_COMPLETION(context->response_event);
4366 vos_spin_lock_release(&hdd_context_lock);
4367
Dino Myclee8843b32014-07-04 14:21:45 +05304368 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304369 if (!HAL_STATUS_SUCCESS(status)) {
4370 hddLog(VOS_TRACE_LEVEL_ERROR,
4371 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304372 return -EINVAL;
4373 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304374
4375 rc = wait_for_completion_timeout(&context->response_event,
4376 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4377 if (!rc) {
4378 hddLog(LOGE, FL("Target response timed out"));
4379 return -ETIMEDOUT;
4380 }
4381
4382 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4383 if (ret)
4384 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4385
4386 return ret;
4387
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304388 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304389 return 0;
4390}
4391
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304392static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4393 struct wireless_dev *wdev,
4394 const void *data, int dataLen)
4395{
4396 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304397
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398 vos_ssr_protect(__func__);
4399 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4400 vos_ssr_unprotect(__func__);
4401
4402 return ret;
4403}
4404
4405static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4406 struct wireless_dev *wdev,
4407 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304408{
Dino Myclee8843b32014-07-04 14:21:45 +05304409 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410 struct net_device *dev = wdev->netdev;
4411 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4412 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4413 struct nlattr
4414 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4415 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304416 struct hdd_ext_scan_context *context;
4417 unsigned long rc;
4418 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304420 ENTER();
4421
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304422 if (VOS_FTM_MODE == hdd_get_conparam()) {
4423 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4424 return -EINVAL;
4425 }
4426
Dino Mycle6fb96c12014-06-10 11:52:40 +05304427 status = wlan_hdd_validate_context(pHddCtx);
4428 if (0 != status)
4429 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304430 return -EINVAL;
4431 }
Dino Myclee8843b32014-07-04 14:21:45 +05304432 /* check the EXTScan Capability */
4433 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304434 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4435 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304436 {
4437 hddLog(VOS_TRACE_LEVEL_ERROR,
4438 FL("EXTScan not enabled/supported by Firmware"));
4439 return -EINVAL;
4440 }
4441
Dino Mycle6fb96c12014-06-10 11:52:40 +05304442 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4443 data, dataLen,
4444 wlan_hdd_extscan_config_policy)) {
4445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4446 return -EINVAL;
4447 }
4448 /* Parse and fetch request Id */
4449 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4451 return -EINVAL;
4452 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304453
Dino Myclee8843b32014-07-04 14:21:45 +05304454 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304455 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4456
Dino Myclee8843b32014-07-04 14:21:45 +05304457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304458
Dino Myclee8843b32014-07-04 14:21:45 +05304459 reqMsg.sessionId = pAdapter->sessionId;
4460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461
4462 /* Parse and fetch flush parameter */
4463 if (!tb
4464 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4465 {
4466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4467 goto failed;
4468 }
Dino Myclee8843b32014-07-04 14:21:45 +05304469 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304474 spin_lock(&hdd_context_lock);
4475 context = &pHddCtx->ext_scan_context;
4476 context->request_id = reqMsg.requestId;
4477 context->ignore_cached_results = false;
4478 INIT_COMPLETION(context->response_event);
4479 spin_unlock(&hdd_context_lock);
4480
Dino Myclee8843b32014-07-04 14:21:45 +05304481 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304482 if (!HAL_STATUS_SUCCESS(status)) {
4483 hddLog(VOS_TRACE_LEVEL_ERROR,
4484 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304485 return -EINVAL;
4486 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304487
4488 rc = wait_for_completion_timeout(&context->response_event,
4489 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4490 if (!rc) {
4491 hddLog(LOGE, FL("Target response timed out"));
4492 retval = -ETIMEDOUT;
4493 spin_lock(&hdd_context_lock);
4494 context->ignore_cached_results = true;
4495 spin_unlock(&hdd_context_lock);
4496 } else {
4497 spin_lock(&hdd_context_lock);
4498 retval = context->response_status;
4499 spin_unlock(&hdd_context_lock);
4500 }
4501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304502 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304503 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
4505failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506 return -EINVAL;
4507}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304508static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4509 struct wireless_dev *wdev,
4510 const void *data, int dataLen)
4511{
4512 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304514 vos_ssr_protect(__func__);
4515 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4516 vos_ssr_unprotect(__func__);
4517
4518 return ret;
4519}
4520
4521static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304522 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304523 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304524{
4525 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4526 struct net_device *dev = wdev->netdev;
4527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4528 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4529 struct nlattr
4530 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4531 struct nlattr
4532 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4533 struct nlattr *apTh;
4534 eHalStatus status;
4535 tANI_U8 i = 0;
4536 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304537 struct hdd_ext_scan_context *context;
4538 tANI_U32 request_id;
4539 unsigned long rc;
4540 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304542 ENTER();
4543
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304544 if (VOS_FTM_MODE == hdd_get_conparam()) {
4545 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4546 return -EINVAL;
4547 }
4548
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 status = wlan_hdd_validate_context(pHddCtx);
4550 if (0 != status)
4551 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304552 return -EINVAL;
4553 }
Dino Myclee8843b32014-07-04 14:21:45 +05304554 /* check the EXTScan Capability */
4555 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304556 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4557 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304558 {
4559 hddLog(VOS_TRACE_LEVEL_ERROR,
4560 FL("EXTScan not enabled/supported by Firmware"));
4561 return -EINVAL;
4562 }
4563
Dino Mycle6fb96c12014-06-10 11:52:40 +05304564 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4565 data, dataLen,
4566 wlan_hdd_extscan_config_policy)) {
4567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4568 return -EINVAL;
4569 }
4570
4571 /* Parse and fetch request Id */
4572 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4573 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4574 return -EINVAL;
4575 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304576 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4577 vos_mem_malloc(sizeof(*pReqMsg));
4578 if (!pReqMsg) {
4579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4580 return -ENOMEM;
4581 }
4582
Dino Myclee8843b32014-07-04 14:21:45 +05304583
Dino Mycle6fb96c12014-06-10 11:52:40 +05304584 pReqMsg->requestId = nla_get_u32(
4585 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4587
4588 /* Parse and fetch number of APs */
4589 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4591 goto fail;
4592 }
4593
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304594 /* Parse and fetch lost ap sample size */
4595 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4596 hddLog(LOGE, FL("attr lost ap sample size failed"));
4597 goto fail;
4598 }
4599
4600 pReqMsg->lostBssidSampleSize = nla_get_u32(
4601 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4602 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4603
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604 pReqMsg->sessionId = pAdapter->sessionId;
4605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4606
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304607 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4610 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4611 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4612 goto fail;
4613 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615
4616 nla_for_each_nested(apTh,
4617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304618 if (i == pReqMsg->numBssid) {
4619 hddLog(LOGW, FL("Ignoring excess AP"));
4620 break;
4621 }
4622
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4624 nla_data(apTh), nla_len(apTh),
4625 NULL)) {
4626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4627 goto fail;
4628 }
4629
4630 /* Parse and fetch MAC address */
4631 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4633 goto fail;
4634 }
4635 memcpy(pReqMsg->ap[i].bssid, nla_data(
4636 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4637 sizeof(tSirMacAddr));
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4639
4640 /* Parse and fetch low RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].low = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4648
4649 /* Parse and fetch high RSSI */
4650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4652 goto fail;
4653 }
4654 pReqMsg->ap[i].high = nla_get_s32(
4655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4656 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4657 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 i++;
4659 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304660
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304661 if (i < pReqMsg->numBssid) {
4662 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4663 i, pReqMsg->numBssid);
4664 pReqMsg->numBssid = i;
4665 }
4666
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304667 context = &pHddCtx->ext_scan_context;
4668 spin_lock(&hdd_context_lock);
4669 INIT_COMPLETION(context->response_event);
4670 context->request_id = request_id = pReqMsg->requestId;
4671 spin_unlock(&hdd_context_lock);
4672
Dino Mycle6fb96c12014-06-10 11:52:40 +05304673 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4674 if (!HAL_STATUS_SUCCESS(status)) {
4675 hddLog(VOS_TRACE_LEVEL_ERROR,
4676 FL("sme_SetBssHotlist failed(err=%d)"), status);
4677 vos_mem_free(pReqMsg);
4678 return -EINVAL;
4679 }
4680
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304681 /* request was sent -- wait for the response */
4682 rc = wait_for_completion_timeout(&context->response_event,
4683 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4684
4685 if (!rc) {
4686 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4687 retval = -ETIMEDOUT;
4688 } else {
4689 spin_lock(&hdd_context_lock);
4690 if (context->request_id == request_id)
4691 retval = context->response_status;
4692 else
4693 retval = -EINVAL;
4694 spin_unlock(&hdd_context_lock);
4695 }
4696
Dino Myclee8843b32014-07-04 14:21:45 +05304697 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304698 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304699 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700
4701fail:
4702 vos_mem_free(pReqMsg);
4703 return -EINVAL;
4704}
4705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304706static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4707 struct wireless_dev *wdev,
4708 const void *data, int dataLen)
4709{
4710 int ret = 0;
4711
4712 vos_ssr_protect(__func__);
4713 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4714 dataLen);
4715 vos_ssr_unprotect(__func__);
4716
4717 return ret;
4718}
4719
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304720static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304721 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304722 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304723{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304724 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4725 struct net_device *dev = wdev->netdev;
4726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4727 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4728 uint8_t num_channels = 0;
4729 uint8_t num_chan_new = 0;
4730 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304731 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304732 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304733 tWifiBand wifiBand;
4734 eHalStatus status;
4735 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304736 tANI_U8 i,j,k;
4737 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304739 ENTER();
4740
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741 status = wlan_hdd_validate_context(pHddCtx);
4742 if (0 != status)
4743 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 return -EINVAL;
4745 }
Dino Myclee8843b32014-07-04 14:21:45 +05304746
Dino Mycle6fb96c12014-06-10 11:52:40 +05304747 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4748 data, dataLen,
4749 wlan_hdd_extscan_config_policy)) {
4750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4751 return -EINVAL;
4752 }
4753
4754 /* Parse and fetch request Id */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4757 return -EINVAL;
4758 }
4759 requestId = nla_get_u32(
4760 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4761 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4762
4763 /* Parse and fetch wifi band */
4764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4765 {
4766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4767 return -EINVAL;
4768 }
4769 wifiBand = nla_get_u32(
4770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4772
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304773 /* Parse and fetch max channels */
4774 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4775 {
4776 hddLog(LOGE, FL("attr max channels failed"));
4777 return -EINVAL;
4778 }
4779 maxChannels = nla_get_u32(
4780 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4781 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4782
Dino Mycle6fb96c12014-06-10 11:52:40 +05304783 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304784 wifiBand, chan_list,
4785 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304786 if (eHAL_STATUS_SUCCESS != status) {
4787 hddLog(VOS_TRACE_LEVEL_ERROR,
4788 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4789 return -EINVAL;
4790 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304791
Agrawal Ashish16abf782016-08-18 22:42:59 +05304792 num_channels = VOS_MIN(num_channels, maxChannels);
4793 num_chan_new = num_channels;
4794 /* remove the indoor only channels if iface is SAP */
4795 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4796 {
4797 num_chan_new = 0;
4798 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304799 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304800 if (wiphy->bands[j] == NULL)
4801 continue;
4802 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4803 if ((chan_list[i] ==
4804 wiphy->bands[j]->channels[k].center_freq) &&
4805 (!(wiphy->bands[j]->channels[k].flags &
4806 IEEE80211_CHAN_INDOOR_ONLY))) {
4807 chan_list[num_chan_new] = chan_list[i];
4808 num_chan_new++;
4809 }
4810 }
4811 }
4812 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304813
Agrawal Ashish16abf782016-08-18 22:42:59 +05304814 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4815 for (i = 0; i < num_chan_new; i++)
4816 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4817 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818
4819 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304820 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304821 NLMSG_HDRLEN);
4822
4823 if (!replySkb) {
4824 hddLog(VOS_TRACE_LEVEL_ERROR,
4825 FL("valid channels: buffer alloc fail"));
4826 return -EINVAL;
4827 }
4828 if (nla_put_u32(replySkb,
4829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304830 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304831 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304832 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304833
4834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4835 kfree_skb(replySkb);
4836 return -EINVAL;
4837 }
4838
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304839 ret = cfg80211_vendor_cmd_reply(replySkb);
4840
4841 EXIT();
4842 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843}
4844
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304845static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4846 struct wireless_dev *wdev,
4847 const void *data, int dataLen)
4848{
4849 int ret = 0;
4850
4851 vos_ssr_protect(__func__);
4852 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4853 dataLen);
4854 vos_ssr_unprotect(__func__);
4855
4856 return ret;
4857}
4858
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304859static int hdd_extscan_start_fill_bucket_channel_spec(
4860 hdd_context_t *pHddCtx,
4861 tpSirEXTScanStartReqParams pReqMsg,
4862 struct nlattr **tb)
4863{
4864 struct nlattr *bucket[
4865 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4866 struct nlattr *channel[
4867 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4868 struct nlattr *buckets;
4869 struct nlattr *channels;
4870 int rem1, rem2;
4871 eHalStatus status;
4872 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304874 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4875 tANI_U32 passive_max_chn_time, active_max_chn_time;
4876
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304877 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 bktIndex = 0;
4879
4880 nla_for_each_nested(buckets,
4881 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304882 if (bktIndex >= expected_buckets) {
4883 hddLog(LOGW, FL("ignoring excess buckets"));
4884 break;
4885 }
4886
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304887 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304888 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4889 nla_data(buckets), nla_len(buckets),
4890 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304891 hddLog(LOGE, FL("nla_parse failed"));
4892 return -EINVAL;
4893 }
4894
4895 /* Parse and fetch bucket spec */
4896 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4897 hddLog(LOGE, FL("attr bucket index failed"));
4898 return -EINVAL;
4899 }
4900 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4901 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4902 hddLog(LOG1, FL("Bucket spec Index %d"),
4903 pReqMsg->buckets[bktIndex].bucket);
4904
4905 /* Parse and fetch wifi band */
4906 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4907 hddLog(LOGE, FL("attr wifi band failed"));
4908 return -EINVAL;
4909 }
4910 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4911 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4912 hddLog(LOG1, FL("Wifi band %d"),
4913 pReqMsg->buckets[bktIndex].band);
4914
4915 /* Parse and fetch period */
4916 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4917 hddLog(LOGE, FL("attr period failed"));
4918 return -EINVAL;
4919 }
4920 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4921 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4922 hddLog(LOG1, FL("period %d"),
4923 pReqMsg->buckets[bktIndex].period);
4924
4925 /* Parse and fetch report events */
4926 if (!bucket[
4927 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4928 hddLog(LOGE, FL("attr report events failed"));
4929 return -EINVAL;
4930 }
4931 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4932 bucket[
4933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4934 hddLog(LOG1, FL("report events %d"),
4935 pReqMsg->buckets[bktIndex].reportEvents);
4936
4937 /* Parse and fetch max period */
4938 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4939 hddLog(LOGE, FL("attr max period failed"));
4940 return -EINVAL;
4941 }
4942 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4943 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4944 hddLog(LOG1, FL("max period %u"),
4945 pReqMsg->buckets[bktIndex].max_period);
4946
4947 /* Parse and fetch exponent */
4948 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4949 hddLog(LOGE, FL("attr exponent failed"));
4950 return -EINVAL;
4951 }
4952 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4953 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4954 hddLog(LOG1, FL("exponent %u"),
4955 pReqMsg->buckets[bktIndex].exponent);
4956
4957 /* Parse and fetch step count */
4958 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4959 hddLog(LOGE, FL("attr step count failed"));
4960 return -EINVAL;
4961 }
4962 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4963 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4964 hddLog(LOG1, FL("Step count %u"),
4965 pReqMsg->buckets[bktIndex].step_count);
4966
4967 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4968 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4969
4970 /* Framework shall pass the channel list if the input WiFi band is
4971 * WIFI_BAND_UNSPECIFIED.
4972 * If the input WiFi band is specified (any value other than
4973 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4974 */
4975 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4976 numChannels = 0;
4977 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4978 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4979 pReqMsg->buckets[bktIndex].band,
4980 chanList, &numChannels);
4981 if (!HAL_STATUS_SUCCESS(status)) {
4982 hddLog(LOGE,
4983 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4984 status);
4985 return -EINVAL;
4986 }
4987
4988 pReqMsg->buckets[bktIndex].numChannels =
4989 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4990 hddLog(LOG1, FL("Num channels %d"),
4991 pReqMsg->buckets[bktIndex].numChannels);
4992
4993 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4994 j++) {
4995 pReqMsg->buckets[bktIndex].channels[j].channel =
4996 chanList[j];
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 chnlClass = 0;
4999 if (CSR_IS_CHANNEL_DFS(
5000 vos_freq_to_chan(chanList[j]))) {
5001 pReqMsg->buckets[bktIndex].channels[j].
5002 passive = 1;
5003 pReqMsg->buckets[bktIndex].channels[j].
5004 dwellTimeMs = passive_max_chn_time;
5005 } else {
5006 pReqMsg->buckets[bktIndex].channels[j].
5007 passive = 0;
5008 pReqMsg->buckets[bktIndex].channels[j].
5009 dwellTimeMs = active_max_chn_time;
5010 }
5011
5012 hddLog(LOG1,
5013 "Channel %u Passive %u Dwell time %u ms",
5014 pReqMsg->buckets[bktIndex].channels[j].channel,
5015 pReqMsg->buckets[bktIndex].channels[j].passive,
5016 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5017 }
5018
5019 bktIndex++;
5020 continue;
5021 }
5022
5023 /* Parse and fetch number of channels */
5024 if (!bucket[
5025 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5026 hddLog(LOGE, FL("attr num channels failed"));
5027 return -EINVAL;
5028 }
5029
5030 pReqMsg->buckets[bktIndex].numChannels =
5031 nla_get_u32(bucket[
5032 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5033 hddLog(LOG1, FL("num channels %d"),
5034 pReqMsg->buckets[bktIndex].numChannels);
5035
5036 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5037 hddLog(LOGE, FL("attr channel spec failed"));
5038 return -EINVAL;
5039 }
5040
5041 j = 0;
5042 nla_for_each_nested(channels,
5043 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5044 if (nla_parse(channel,
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5046 nla_data(channels), nla_len(channels),
5047 wlan_hdd_extscan_config_policy)) {
5048 hddLog(LOGE, FL("nla_parse failed"));
5049 return -EINVAL;
5050 }
5051
5052 /* Parse and fetch channel */
5053 if (!channel[
5054 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5055 hddLog(LOGE, FL("attr channel failed"));
5056 return -EINVAL;
5057 }
5058 pReqMsg->buckets[bktIndex].channels[j].channel =
5059 nla_get_u32(channel[
5060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5061 hddLog(LOG1, FL("channel %u"),
5062 pReqMsg->buckets[bktIndex].channels[j].channel);
5063
5064 /* Parse and fetch dwell time */
5065 if (!channel[
5066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5067 hddLog(LOGE, FL("attr dwelltime failed"));
5068 return -EINVAL;
5069 }
5070 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5071 nla_get_u32(channel[
5072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5073
5074 hddLog(LOG1, FL("Dwell time (%u ms)"),
5075 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5076
5077
5078 /* Parse and fetch channel spec passive */
5079 if (!channel[
5080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5081 hddLog(LOGE,
5082 FL("attr channel spec passive failed"));
5083 return -EINVAL;
5084 }
5085 pReqMsg->buckets[bktIndex].channels[j].passive =
5086 nla_get_u8(channel[
5087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5088 hddLog(LOG1, FL("Chnl spec passive %u"),
5089 pReqMsg->buckets[bktIndex].channels[j].passive);
5090
5091 j++;
5092 }
5093
5094 bktIndex++;
5095 }
5096
5097 return 0;
5098}
5099
5100
5101/*
5102 * define short names for the global vendor params
5103 * used by wlan_hdd_cfg80211_extscan_start()
5104 */
5105#define PARAM_MAX \
5106QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5107#define PARAM_REQUEST_ID \
5108QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5109#define PARAM_BASE_PERIOD \
5110QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5111#define PARAM_MAX_AP_PER_SCAN \
5112QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5113#define PARAM_RPT_THRHLD_PERCENT \
5114QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5115#define PARAM_RPT_THRHLD_NUM_SCANS \
5116QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5117#define PARAM_NUM_BUCKETS \
5118QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5119
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305120static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305122 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305123{
Dino Myclee8843b32014-07-04 14:21:45 +05305124 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305125 struct net_device *dev = wdev->netdev;
5126 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 struct nlattr *tb[PARAM_MAX + 1];
5129 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305131 tANI_U32 request_id;
5132 struct hdd_ext_scan_context *context;
5133 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305135 ENTER();
5136
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305137 if (VOS_FTM_MODE == hdd_get_conparam()) {
5138 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5139 return -EINVAL;
5140 }
5141
Dino Mycle6fb96c12014-06-10 11:52:40 +05305142 status = wlan_hdd_validate_context(pHddCtx);
5143 if (0 != status)
5144 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145 return -EINVAL;
5146 }
Dino Myclee8843b32014-07-04 14:21:45 +05305147 /* check the EXTScan Capability */
5148 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305149 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5150 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305151 {
5152 hddLog(VOS_TRACE_LEVEL_ERROR,
5153 FL("EXTScan not enabled/supported by Firmware"));
5154 return -EINVAL;
5155 }
5156
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305157 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305158 data, dataLen,
5159 wlan_hdd_extscan_config_policy)) {
5160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5161 return -EINVAL;
5162 }
5163
5164 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305165 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5167 return -EINVAL;
5168 }
5169
Dino Myclee8843b32014-07-04 14:21:45 +05305170 pReqMsg = (tpSirEXTScanStartReqParams)
5171 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305172 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305173 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5174 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305175 }
5176
5177 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5180
5181 pReqMsg->sessionId = pAdapter->sessionId;
5182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5183
5184 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305185 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5187 goto fail;
5188 }
5189 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305190 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305191 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5192 pReqMsg->basePeriod);
5193
5194 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305195 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5197 goto fail;
5198 }
5199 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5202 pReqMsg->maxAPperScan);
5203
5204 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305205 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5207 goto fail;
5208 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305209 pReqMsg->reportThresholdPercent = nla_get_u8(
5210 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305212 pReqMsg->reportThresholdPercent);
5213
5214 /* Parse and fetch report threshold num scans */
5215 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5216 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5217 goto fail;
5218 }
5219 pReqMsg->reportThresholdNumScans = nla_get_u8(
5220 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5221 hddLog(LOG1, FL("Report Threshold num scans %d"),
5222 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305223
5224 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305225 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5227 goto fail;
5228 }
5229 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305230 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305231 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5232 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5233 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5234 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5235 }
5236 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5237 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305238
Dino Mycle6fb96c12014-06-10 11:52:40 +05305239 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5241 goto fail;
5242 }
5243
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305244 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305245
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305246 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5247 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305248
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305249 context = &pHddCtx->ext_scan_context;
5250 spin_lock(&hdd_context_lock);
5251 INIT_COMPLETION(context->response_event);
5252 context->request_id = request_id = pReqMsg->requestId;
5253 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305254
Dino Mycle6fb96c12014-06-10 11:52:40 +05305255 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5256 if (!HAL_STATUS_SUCCESS(status)) {
5257 hddLog(VOS_TRACE_LEVEL_ERROR,
5258 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305259 goto fail;
5260 }
5261
Srinivas Dasari91727c12016-03-23 17:59:06 +05305262 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5263
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305264 /* request was sent -- wait for the response */
5265 rc = wait_for_completion_timeout(&context->response_event,
5266 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5267
5268 if (!rc) {
5269 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5270 retval = -ETIMEDOUT;
5271 } else {
5272 spin_lock(&hdd_context_lock);
5273 if (context->request_id == request_id)
5274 retval = context->response_status;
5275 else
5276 retval = -EINVAL;
5277 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305278 }
5279
Dino Myclee8843b32014-07-04 14:21:45 +05305280 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305282 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305283
5284fail:
5285 vos_mem_free(pReqMsg);
5286 return -EINVAL;
5287}
5288
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305289/*
5290 * done with short names for the global vendor params
5291 * used by wlan_hdd_cfg80211_extscan_start()
5292 */
5293#undef PARAM_MAX
5294#undef PARAM_REQUEST_ID
5295#undef PARAM_BASE_PERIOD
5296#undef PARAMS_MAX_AP_PER_SCAN
5297#undef PARAMS_RPT_THRHLD_PERCENT
5298#undef PARAMS_RPT_THRHLD_NUM_SCANS
5299#undef PARAMS_NUM_BUCKETS
5300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305301static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5302 struct wireless_dev *wdev,
5303 const void *data, int dataLen)
5304{
5305 int ret = 0;
5306
5307 vos_ssr_protect(__func__);
5308 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5309 vos_ssr_unprotect(__func__);
5310
5311 return ret;
5312}
5313
5314static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305315 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305316 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305317{
Dino Myclee8843b32014-07-04 14:21:45 +05305318 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319 struct net_device *dev = wdev->netdev;
5320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5321 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5322 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5323 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305324 int retval;
5325 unsigned long rc;
5326 struct hdd_ext_scan_context *context;
5327 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305329 ENTER();
5330
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305331 if (VOS_FTM_MODE == hdd_get_conparam()) {
5332 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5333 return -EINVAL;
5334 }
5335
Dino Mycle6fb96c12014-06-10 11:52:40 +05305336 status = wlan_hdd_validate_context(pHddCtx);
5337 if (0 != status)
5338 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305339 return -EINVAL;
5340 }
Dino Myclee8843b32014-07-04 14:21:45 +05305341 /* check the EXTScan Capability */
5342 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305343 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5344 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305345 {
5346 hddLog(VOS_TRACE_LEVEL_ERROR,
5347 FL("EXTScan not enabled/supported by Firmware"));
5348 return -EINVAL;
5349 }
5350
Dino Mycle6fb96c12014-06-10 11:52:40 +05305351 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5352 data, dataLen,
5353 wlan_hdd_extscan_config_policy)) {
5354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5355 return -EINVAL;
5356 }
5357
5358 /* Parse and fetch request Id */
5359 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5361 return -EINVAL;
5362 }
5363
Dino Myclee8843b32014-07-04 14:21:45 +05305364 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305365 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 reqMsg.sessionId = pAdapter->sessionId;
5369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305370
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305371 context = &pHddCtx->ext_scan_context;
5372 spin_lock(&hdd_context_lock);
5373 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305374 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 spin_unlock(&hdd_context_lock);
5376
Dino Myclee8843b32014-07-04 14:21:45 +05305377 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378 if (!HAL_STATUS_SUCCESS(status)) {
5379 hddLog(VOS_TRACE_LEVEL_ERROR,
5380 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305381 return -EINVAL;
5382 }
5383
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305384 /* request was sent -- wait for the response */
5385 rc = wait_for_completion_timeout(&context->response_event,
5386 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5387
5388 if (!rc) {
5389 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5390 retval = -ETIMEDOUT;
5391 } else {
5392 spin_lock(&hdd_context_lock);
5393 if (context->request_id == request_id)
5394 retval = context->response_status;
5395 else
5396 retval = -EINVAL;
5397 spin_unlock(&hdd_context_lock);
5398 }
5399
5400 return retval;
5401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305402 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305403 return 0;
5404}
5405
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305406static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5407 struct wireless_dev *wdev,
5408 const void *data, int dataLen)
5409{
5410 int ret = 0;
5411
5412 vos_ssr_protect(__func__);
5413 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5414 vos_ssr_unprotect(__func__);
5415
5416 return ret;
5417}
5418
5419static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305420 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305421 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305422{
Dino Myclee8843b32014-07-04 14:21:45 +05305423 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424 struct net_device *dev = wdev->netdev;
5425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5426 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5427 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5428 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305429 struct hdd_ext_scan_context *context;
5430 tANI_U32 request_id;
5431 unsigned long rc;
5432 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305434 ENTER();
5435
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305436 if (VOS_FTM_MODE == hdd_get_conparam()) {
5437 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5438 return -EINVAL;
5439 }
5440
Dino Mycle6fb96c12014-06-10 11:52:40 +05305441 status = wlan_hdd_validate_context(pHddCtx);
5442 if (0 != status)
5443 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305444 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305445 return -EINVAL;
5446 }
Dino Myclee8843b32014-07-04 14:21:45 +05305447 /* check the EXTScan Capability */
5448 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305449 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5450 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305451 {
5452 hddLog(VOS_TRACE_LEVEL_ERROR,
5453 FL("EXTScan not enabled/supported by Firmware"));
5454 return -EINVAL;
5455 }
5456
Dino Mycle6fb96c12014-06-10 11:52:40 +05305457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5458 data, dataLen,
5459 wlan_hdd_extscan_config_policy)) {
5460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5461 return -EINVAL;
5462 }
5463
5464 /* Parse and fetch request Id */
5465 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5467 return -EINVAL;
5468 }
5469
Dino Myclee8843b32014-07-04 14:21:45 +05305470 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305471 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 reqMsg.sessionId = pAdapter->sessionId;
5475 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305476
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305477 context = &pHddCtx->ext_scan_context;
5478 spin_lock(&hdd_context_lock);
5479 INIT_COMPLETION(context->response_event);
5480 context->request_id = request_id = reqMsg.requestId;
5481 spin_unlock(&hdd_context_lock);
5482
Dino Myclee8843b32014-07-04 14:21:45 +05305483 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305484 if (!HAL_STATUS_SUCCESS(status)) {
5485 hddLog(VOS_TRACE_LEVEL_ERROR,
5486 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305487 return -EINVAL;
5488 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305489
5490 /* request was sent -- wait for the response */
5491 rc = wait_for_completion_timeout(&context->response_event,
5492 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5493 if (!rc) {
5494 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5495 retval = -ETIMEDOUT;
5496 } else {
5497 spin_lock(&hdd_context_lock);
5498 if (context->request_id == request_id)
5499 retval = context->response_status;
5500 else
5501 retval = -EINVAL;
5502 spin_unlock(&hdd_context_lock);
5503 }
5504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305506 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305507}
5508
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305509static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5510 struct wireless_dev *wdev,
5511 const void *data, int dataLen)
5512{
5513 int ret = 0;
5514
5515 vos_ssr_protect(__func__);
5516 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5517 vos_ssr_unprotect(__func__);
5518
5519 return ret;
5520}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305521#endif /* WLAN_FEATURE_EXTSCAN */
5522
Atul Mittal115287b2014-07-08 13:26:33 +05305523/*EXT TDLS*/
5524static const struct nla_policy
5525wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5526{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305527 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5528 .type = NLA_UNSPEC,
5529 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305530 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5531 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5532 {.type = NLA_S32 },
5533 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5534 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5540{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305541 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5542 .type = NLA_UNSPEC,
5543 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305544
5545};
5546
5547static const struct nla_policy
5548wlan_hdd_tdls_config_state_change_policy[
5549 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5550{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305551 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5552 .type = NLA_UNSPEC,
5553 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305554 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5555 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305556 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5557 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5558 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305559
5560};
5561
5562static const struct nla_policy
5563wlan_hdd_tdls_config_get_status_policy[
5564 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5565{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305566 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5567 .type = NLA_UNSPEC,
5568 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305569 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5570 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305571 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5572 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5573 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305574
5575};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305576
5577static const struct nla_policy
5578wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5579{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305580 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5581 .type = NLA_UNSPEC,
5582 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305583};
5584
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305585static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305586 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305587 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 int data_len)
5589{
5590
5591 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5592 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5593
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305594 ENTER();
5595
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305597 return -EINVAL;
5598 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305599 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305600 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305601 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305602 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305603 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305604 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305605 return -ENOTSUPP;
5606 }
5607
5608 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5609 data, data_len, wlan_hdd_mac_config)) {
5610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5611 return -EINVAL;
5612 }
5613
5614 /* Parse and fetch mac address */
5615 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5617 return -EINVAL;
5618 }
5619
5620 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5621 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5622 VOS_MAC_ADDR_LAST_3_BYTES);
5623
Siddharth Bhal76972212014-10-15 16:22:51 +05305624 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5625
5626 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305627 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5628 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305629 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5630 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5631 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5632 {
5633 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5634 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5635 VOS_MAC_ADDRESS_LEN);
5636 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305637 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305638
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305639 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5640 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305642 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305643 return 0;
5644}
5645
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305646static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5647 struct wireless_dev *wdev,
5648 const void *data,
5649 int data_len)
5650{
5651 int ret = 0;
5652
5653 vos_ssr_protect(__func__);
5654 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5655 vos_ssr_unprotect(__func__);
5656
5657 return ret;
5658}
5659
5660static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305661 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305662 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305663 int data_len)
5664{
5665 u8 peer[6] = {0};
5666 struct net_device *dev = wdev->netdev;
5667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5668 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5669 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5670 eHalStatus ret;
5671 tANI_S32 state;
5672 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305673 tANI_S32 global_operating_class = 0;
5674 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305675 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305676 int retVal;
5677
5678 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305679
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305680 if (!pAdapter) {
5681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5682 return -EINVAL;
5683 }
5684
Atul Mittal115287b2014-07-08 13:26:33 +05305685 ret = wlan_hdd_validate_context(pHddCtx);
5686 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305687 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305688 return -EINVAL;
5689 }
5690 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305692 return -ENOTSUPP;
5693 }
5694 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5695 data, data_len,
5696 wlan_hdd_tdls_config_get_status_policy)) {
5697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5698 return -EINVAL;
5699 }
5700
5701 /* Parse and fetch mac address */
5702 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5704 return -EINVAL;
5705 }
5706
5707 memcpy(peer, nla_data(
5708 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5709 sizeof(peer));
5710 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5711
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305712 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305713
Atul Mittal115287b2014-07-08 13:26:33 +05305714 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305715 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305716 NLMSG_HDRLEN);
5717
5718 if (!skb) {
5719 hddLog(VOS_TRACE_LEVEL_ERROR,
5720 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5721 return -EINVAL;
5722 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305723 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 +05305724 reason,
5725 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305726 global_operating_class,
5727 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305728 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305729 if (nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5731 state) ||
5732 nla_put_s32(skb,
5733 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5734 reason) ||
5735 nla_put_s32(skb,
5736 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5737 global_operating_class) ||
5738 nla_put_s32(skb,
5739 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5740 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305741
5742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5743 goto nla_put_failure;
5744 }
5745
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305746 retVal = cfg80211_vendor_cmd_reply(skb);
5747 EXIT();
5748 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305749
5750nla_put_failure:
5751 kfree_skb(skb);
5752 return -EINVAL;
5753}
5754
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305755static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5756 struct wireless_dev *wdev,
5757 const void *data,
5758 int data_len)
5759{
5760 int ret = 0;
5761
5762 vos_ssr_protect(__func__);
5763 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5764 vos_ssr_unprotect(__func__);
5765
5766 return ret;
5767}
5768
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305769static int wlan_hdd_cfg80211_exttdls_callback(
5770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5771 const tANI_U8* mac,
5772#else
5773 tANI_U8* mac,
5774#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305775 tANI_S32 state,
5776 tANI_S32 reason,
5777 void *ctx)
5778{
5779 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305780 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305781 tANI_S32 global_operating_class = 0;
5782 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305783 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305784
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305785 ENTER();
5786
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305787 if (!pAdapter) {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5789 return -EINVAL;
5790 }
5791
5792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305793 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305795 return -EINVAL;
5796 }
5797
5798 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305800 return -ENOTSUPP;
5801 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305802 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5804 NULL,
5805#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305806 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5807 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5808 GFP_KERNEL);
5809
5810 if (!skb) {
5811 hddLog(VOS_TRACE_LEVEL_ERROR,
5812 FL("cfg80211_vendor_event_alloc failed"));
5813 return -EINVAL;
5814 }
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305816 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5817 reason,
5818 state,
5819 global_operating_class,
5820 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305821 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5822 MAC_ADDR_ARRAY(mac));
5823
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305824 if (nla_put(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5826 VOS_MAC_ADDR_SIZE, mac) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5829 state) ||
5830 nla_put_s32(skb,
5831 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5832 reason) ||
5833 nla_put_s32(skb,
5834 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5835 channel) ||
5836 nla_put_s32(skb,
5837 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5838 global_operating_class)
5839 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5841 goto nla_put_failure;
5842 }
5843
5844 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305845 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305846 return (0);
5847
5848nla_put_failure:
5849 kfree_skb(skb);
5850 return -EINVAL;
5851}
5852
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305853static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305854 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305855 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305856 int data_len)
5857{
5858 u8 peer[6] = {0};
5859 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5861 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5862 eHalStatus status;
5863 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305864 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305865 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305866
5867 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305868
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305869 if (!dev) {
5870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5871 return -EINVAL;
5872 }
5873
5874 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5875 if (!pAdapter) {
5876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5877 return -EINVAL;
5878 }
5879
Atul Mittal115287b2014-07-08 13:26:33 +05305880 status = wlan_hdd_validate_context(pHddCtx);
5881 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305883 return -EINVAL;
5884 }
5885 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305887 return -ENOTSUPP;
5888 }
5889 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5890 data, data_len,
5891 wlan_hdd_tdls_config_enable_policy)) {
5892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5893 return -EINVAL;
5894 }
5895
5896 /* Parse and fetch mac address */
5897 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5899 return -EINVAL;
5900 }
5901
5902 memcpy(peer, nla_data(
5903 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5904 sizeof(peer));
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5906
5907 /* Parse and fetch channel */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.channel = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5915
5916 /* Parse and fetch global operating class */
5917 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5919 return -EINVAL;
5920 }
5921 pReqMsg.global_operating_class = nla_get_s32(
5922 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5924 pReqMsg.global_operating_class);
5925
5926 /* Parse and fetch latency ms */
5927 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5929 return -EINVAL;
5930 }
5931 pReqMsg.max_latency_ms = nla_get_s32(
5932 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5933 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5934 pReqMsg.max_latency_ms);
5935
5936 /* Parse and fetch required bandwidth kbps */
5937 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5939 return -EINVAL;
5940 }
5941
5942 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5943 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5945 pReqMsg.min_bandwidth_kbps);
5946
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305947 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305948 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305949 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305950 wlan_hdd_cfg80211_exttdls_callback);
5951
5952 EXIT();
5953 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305954}
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5957 struct wireless_dev *wdev,
5958 const void *data,
5959 int data_len)
5960{
5961 int ret = 0;
5962
5963 vos_ssr_protect(__func__);
5964 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5965 vos_ssr_unprotect(__func__);
5966
5967 return ret;
5968}
5969
5970static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305971 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305972 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305973 int data_len)
5974{
5975 u8 peer[6] = {0};
5976 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5978 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5979 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305980 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305981 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305982
5983 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305984
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305985 if (!dev) {
5986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5987 return -EINVAL;
5988 }
5989
5990 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5991 if (!pAdapter) {
5992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5993 return -EINVAL;
5994 }
5995
Atul Mittal115287b2014-07-08 13:26:33 +05305996 status = wlan_hdd_validate_context(pHddCtx);
5997 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305999 return -EINVAL;
6000 }
6001 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05306002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05306003 return -ENOTSUPP;
6004 }
6005 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
6006 data, data_len,
6007 wlan_hdd_tdls_config_disable_policy)) {
6008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6009 return -EINVAL;
6010 }
6011 /* Parse and fetch mac address */
6012 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6013 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6014 return -EINVAL;
6015 }
6016
6017 memcpy(peer, nla_data(
6018 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6019 sizeof(peer));
6020 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6021
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306022 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6023
6024 EXIT();
6025 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306026}
6027
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306028static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6029 struct wireless_dev *wdev,
6030 const void *data,
6031 int data_len)
6032{
6033 int ret = 0;
6034
6035 vos_ssr_protect(__func__);
6036 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6037 vos_ssr_unprotect(__func__);
6038
6039 return ret;
6040}
6041
Dasari Srinivas7875a302014-09-26 17:50:57 +05306042static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306045 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046{
6047 struct net_device *dev = wdev->netdev;
6048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6050 struct sk_buff *skb = NULL;
6051 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306052 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306053
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306054 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306055
6056 ret = wlan_hdd_validate_context(pHddCtx);
6057 if (0 != ret)
6058 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306059 return ret;
6060 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306061 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6062 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6063 fset |= WIFI_FEATURE_INFRA;
6064 }
6065
6066 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6067 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6068 fset |= WIFI_FEATURE_INFRA_5G;
6069 }
6070
6071#ifdef WLAN_FEATURE_P2P
6072 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6073 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6074 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6075 fset |= WIFI_FEATURE_P2P;
6076 }
6077#endif
6078
6079 /* Soft-AP is supported currently by default */
6080 fset |= WIFI_FEATURE_SOFT_AP;
6081
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306082 /* HOTSPOT is a supplicant feature, enable it by default */
6083 fset |= WIFI_FEATURE_HOTSPOT;
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085#ifdef WLAN_FEATURE_EXTSCAN
6086 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306087 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6088 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6089 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306090 fset |= WIFI_FEATURE_EXTSCAN;
6091 }
6092#endif
6093
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 if (sme_IsFeatureSupportedByFW(NAN)) {
6095 hddLog(LOG1, FL("NAN is supported by firmware"));
6096 fset |= WIFI_FEATURE_NAN;
6097 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306098
6099 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306100 if (sme_IsFeatureSupportedByFW(RTT) &&
6101 pHddCtx->cfg_ini->enable_rtt_support) {
6102 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306103 fset |= WIFI_FEATURE_D2AP_RTT;
6104 }
6105
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306106 if (sme_IsFeatureSupportedByFW(RTT3)) {
6107 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6108 fset |= WIFI_FEATURE_RTT3;
6109 }
6110
Dasari Srinivas7875a302014-09-26 17:50:57 +05306111#ifdef FEATURE_WLAN_BATCH_SCAN
6112 if (fset & WIFI_FEATURE_EXTSCAN) {
6113 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6114 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6115 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6116 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6117 fset |= WIFI_FEATURE_BATCH_SCAN;
6118 }
6119#endif
6120
6121#ifdef FEATURE_WLAN_SCAN_PNO
6122 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6123 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6124 hddLog(LOG1, FL("PNO is supported by firmware"));
6125 fset |= WIFI_FEATURE_PNO;
6126 }
6127#endif
6128
6129 /* STA+STA is supported currently by default */
6130 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6131
6132#ifdef FEATURE_WLAN_TDLS
6133 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6134 sme_IsFeatureSupportedByFW(TDLS)) {
6135 hddLog(LOG1, FL("TDLS is supported by firmware"));
6136 fset |= WIFI_FEATURE_TDLS;
6137 }
6138
6139 /* TDLS_OFFCHANNEL is not supported currently by default */
6140#endif
6141
6142#ifdef WLAN_AP_STA_CONCURRENCY
6143 /* AP+STA concurrency is supported currently by default */
6144 fset |= WIFI_FEATURE_AP_STA;
6145#endif
6146
Mukul Sharma5add0532015-08-17 15:57:47 +05306147#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306148 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6149 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306150 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6151 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306152 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306153#endif
6154
Dasari Srinivas7875a302014-09-26 17:50:57 +05306155 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6156 NLMSG_HDRLEN);
6157
6158 if (!skb) {
6159 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6160 return -EINVAL;
6161 }
6162 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6163
6164 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6165 hddLog(LOGE, FL("nla put fail"));
6166 goto nla_put_failure;
6167 }
6168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306169 ret = cfg80211_vendor_cmd_reply(skb);
6170 EXIT();
6171 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306172
6173nla_put_failure:
6174 kfree_skb(skb);
6175 return -EINVAL;
6176}
6177
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306178static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306179wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6180 struct wireless_dev *wdev,
6181 const void *data, int data_len)
6182{
6183 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306184 vos_ssr_protect(__func__);
6185 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6186 vos_ssr_unprotect(__func__);
6187
6188 return ret;
6189}
6190
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306191
6192static const struct
6193nla_policy
6194qca_wlan_vendor_wifi_logger_get_ring_data_policy
6195[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6196 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6197 = {.type = NLA_U32 },
6198};
6199
6200static int
6201 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6202 struct wireless_dev *wdev,
6203 const void *data,
6204 int data_len)
6205{
6206 int ret;
6207 VOS_STATUS status;
6208 uint32_t ring_id;
6209 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6210 struct nlattr *tb
6211 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6212
6213 ENTER();
6214
6215 ret = wlan_hdd_validate_context(hdd_ctx);
6216 if (0 != ret) {
6217 return ret;
6218 }
6219
6220 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6221 data, data_len,
6222 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6223 hddLog(LOGE, FL("Invalid attribute"));
6224 return -EINVAL;
6225 }
6226
6227 /* Parse and fetch ring id */
6228 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6229 hddLog(LOGE, FL("attr ATTR failed"));
6230 return -EINVAL;
6231 }
6232
6233 ring_id = nla_get_u32(
6234 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6235
6236 hddLog(LOG1, FL("Bug report triggered by framework"));
6237
6238 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6239 WLAN_LOG_INDICATOR_FRAMEWORK,
6240 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306241 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306242 );
6243 if (VOS_STATUS_SUCCESS != status) {
6244 hddLog(LOGE, FL("Failed to trigger bug report"));
6245
6246 return -EINVAL;
6247 }
6248
6249 return 0;
6250
6251
6252}
6253
6254
6255static int
6256 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6257 struct wireless_dev *wdev,
6258 const void *data,
6259 int data_len)
6260{
6261 int ret = 0;
6262
6263 vos_ssr_protect(__func__);
6264 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6265 wdev, data, data_len);
6266 vos_ssr_unprotect(__func__);
6267
6268 return ret;
6269
6270}
6271
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306272#define MAX_CONCURRENT_MATRIX \
6273 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6274#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6275 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6276static const struct nla_policy
6277wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6278 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6279};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281static int
6282__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306284 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306285{
6286 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6287 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306288 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306289 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306290 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6291 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306292
6293 ENTER();
6294
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306295 ret = wlan_hdd_validate_context(pHddCtx);
6296 if (0 != ret)
6297 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306298 return ret;
6299 }
6300
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306301 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6302 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306303 hddLog(LOGE, FL("Invalid ATTR"));
6304 return -EINVAL;
6305 }
6306
6307 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306308 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306309 hddLog(LOGE, FL("Attr max feature set size failed"));
6310 return -EINVAL;
6311 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306312 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306313 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6314
6315 /* Fill feature combination matrix */
6316 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_P2P;
6319
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306320 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6321 WIFI_FEATURE_SOFT_AP;
6322
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306323 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6324 WIFI_FEATURE_SOFT_AP;
6325
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306326 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6327 WIFI_FEATURE_SOFT_AP |
6328 WIFI_FEATURE_P2P;
6329
6330 /* Add more feature combinations here */
6331
6332 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6333 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6334 hddLog(LOG1, "Feature set matrix");
6335 for (i = 0; i < feature_sets; i++)
6336 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6337
6338 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6339 sizeof(u32) * feature_sets +
6340 NLMSG_HDRLEN);
6341
6342 if (reply_skb) {
6343 if (nla_put_u32(reply_skb,
6344 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6345 feature_sets) ||
6346 nla_put(reply_skb,
6347 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6348 sizeof(u32) * feature_sets, feature_set_matrix)) {
6349 hddLog(LOGE, FL("nla put fail"));
6350 kfree_skb(reply_skb);
6351 return -EINVAL;
6352 }
6353
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306354 ret = cfg80211_vendor_cmd_reply(reply_skb);
6355 EXIT();
6356 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306357 }
6358 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6359 return -ENOMEM;
6360
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306361}
6362
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306363#undef MAX_CONCURRENT_MATRIX
6364#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6365
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306366static int
6367wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6368 struct wireless_dev *wdev,
6369 const void *data, int data_len)
6370{
6371 int ret = 0;
6372
6373 vos_ssr_protect(__func__);
6374 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6375 data_len);
6376 vos_ssr_unprotect(__func__);
6377
6378 return ret;
6379}
6380
c_manjeecfd1efb2015-09-25 19:32:34 +05306381
6382static int
6383__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6384 struct wireless_dev *wdev,
6385 const void *data, int data_len)
6386{
6387 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6388 int ret;
6389 ENTER();
6390
6391 ret = wlan_hdd_validate_context(pHddCtx);
6392 if (0 != ret)
6393 {
6394 return ret;
6395 }
6396
6397 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6398 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6399 {
6400 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306401 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306402 }
6403 /*call common API for FW mem dump req*/
6404 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6405
Abhishek Singhc783fa72015-12-09 18:07:34 +05306406 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306407 {
6408 /*indicate to userspace the status of fw mem dump */
6409 wlan_indicate_mem_dump_complete(true);
6410 }
6411 else
6412 {
6413 /*else send failure to userspace */
6414 wlan_indicate_mem_dump_complete(false);
6415 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306416 EXIT();
6417 return ret;
6418}
6419
6420/**
6421 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6422 * @wiphy: pointer to wireless wiphy structure.
6423 * @wdev: pointer to wireless_dev structure.
6424 * @data: Pointer to the NL data.
6425 * @data_len:Length of @data
6426 *
6427 * This is called when wlan driver needs to get the firmware memory dump
6428 * via vendor specific command.
6429 *
6430 * Return: 0 on success, error number otherwise.
6431 */
6432
6433static int
6434wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6435 struct wireless_dev *wdev,
6436 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437{
6438 int ret = 0;
6439 vos_ssr_protect(__func__);
6440 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6441 data_len);
6442 vos_ssr_unprotect(__func__);
6443 return ret;
6444}
c_manjeecfd1efb2015-09-25 19:32:34 +05306445
Sushant Kaushik8e644982015-09-23 12:18:54 +05306446static const struct
6447nla_policy
6448qca_wlan_vendor_wifi_logger_start_policy
6449[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6450 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6451 = {.type = NLA_U32 },
6452 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6453 = {.type = NLA_U32 },
6454 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6455 = {.type = NLA_U32 },
6456};
6457
6458/**
6459 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6460 * or disable the collection of packet statistics from the firmware
6461 * @wiphy: WIPHY structure pointer
6462 * @wdev: Wireless device structure pointer
6463 * @data: Pointer to the data received
6464 * @data_len: Length of the data received
6465 *
6466 * This function is used to enable or disable the collection of packet
6467 * statistics from the firmware
6468 *
6469 * Return: 0 on success and errno on failure
6470 */
6471static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6472 struct wireless_dev *wdev,
6473 const void *data,
6474 int data_len)
6475{
6476 eHalStatus status;
6477 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6478 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6479 tAniWifiStartLog start_log;
6480
6481 status = wlan_hdd_validate_context(hdd_ctx);
6482 if (0 != status) {
6483 return -EINVAL;
6484 }
6485
6486 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6487 data, data_len,
6488 qca_wlan_vendor_wifi_logger_start_policy)) {
6489 hddLog(LOGE, FL("Invalid attribute"));
6490 return -EINVAL;
6491 }
6492
6493 /* Parse and fetch ring id */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6495 hddLog(LOGE, FL("attr ATTR failed"));
6496 return -EINVAL;
6497 }
6498 start_log.ringId = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6500 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6501
6502 /* Parse and fetch verbose level */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6504 hddLog(LOGE, FL("attr verbose_level failed"));
6505 return -EINVAL;
6506 }
6507 start_log.verboseLevel = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6509 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6510
6511 /* Parse and fetch flag */
6512 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6513 hddLog(LOGE, FL("attr flag failed"));
6514 return -EINVAL;
6515 }
6516 start_log.flag = nla_get_u32(
6517 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6518 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6519
6520 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306521 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6522 !vos_isPktStatsEnabled()))
6523
Sushant Kaushik8e644982015-09-23 12:18:54 +05306524 {
6525 hddLog(LOGE, FL("per pkt stats not enabled"));
6526 return -EINVAL;
6527 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306528
Sushant Kaushik33200572015-08-05 16:46:20 +05306529 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306530 return 0;
6531}
6532
6533/**
6534 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6535 * or disable the collection of packet statistics from the firmware
6536 * @wiphy: WIPHY structure pointer
6537 * @wdev: Wireless device structure pointer
6538 * @data: Pointer to the data received
6539 * @data_len: Length of the data received
6540 *
6541 * This function is used to enable or disable the collection of packet
6542 * statistics from the firmware
6543 *
6544 * Return: 0 on success and errno on failure
6545 */
6546static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6547 struct wireless_dev *wdev,
6548 const void *data,
6549 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306550{
6551 int ret = 0;
6552
6553 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306554
6555 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6556 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306557 vos_ssr_unprotect(__func__);
6558
6559 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306560}
6561
6562
Agarwal Ashish738843c2014-09-25 12:27:56 +05306563static const struct nla_policy
6564wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6565 +1] =
6566{
6567 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6568};
6569
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306570static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306571 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306572 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306573 int data_len)
6574{
6575 struct net_device *dev = wdev->netdev;
6576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6577 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6578 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6579 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6580 eHalStatus status;
6581 u32 dfsFlag = 0;
6582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306583 ENTER();
6584
Agarwal Ashish738843c2014-09-25 12:27:56 +05306585 status = wlan_hdd_validate_context(pHddCtx);
6586 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306587 return -EINVAL;
6588 }
6589 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6590 data, data_len,
6591 wlan_hdd_set_no_dfs_flag_config_policy)) {
6592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6593 return -EINVAL;
6594 }
6595
6596 /* Parse and fetch required bandwidth kbps */
6597 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6598 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6599 return -EINVAL;
6600 }
6601
6602 dfsFlag = nla_get_u32(
6603 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6604 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6605 dfsFlag);
6606
6607 pHddCtx->disable_dfs_flag = dfsFlag;
6608
6609 sme_disable_dfs_channel(hHal, dfsFlag);
6610 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306611
6612 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306613 return 0;
6614}
Atul Mittal115287b2014-07-08 13:26:33 +05306615
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306616static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6617 struct wireless_dev *wdev,
6618 const void *data,
6619 int data_len)
6620{
6621 int ret = 0;
6622
6623 vos_ssr_protect(__func__);
6624 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6625 vos_ssr_unprotect(__func__);
6626
6627 return ret;
6628
6629}
6630
Mukul Sharma2a271632014-10-13 14:59:01 +05306631const struct
6632nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6633{
6634 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306635 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6636 .type = NLA_UNSPEC,
6637 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306638};
6639
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306640static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306641 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306642{
6643
6644 u8 bssid[6] = {0};
6645 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6646 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6647 eHalStatus status = eHAL_STATUS_SUCCESS;
6648 v_U32_t isFwrRoamEnabled = FALSE;
6649 int ret;
6650
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306651 ENTER();
6652
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306653 ret = wlan_hdd_validate_context(pHddCtx);
6654 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306655 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306656 }
6657
6658 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6659 data, data_len,
6660 qca_wlan_vendor_attr);
6661 if (ret){
6662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6663 return -EINVAL;
6664 }
6665
6666 /* Parse and fetch Enable flag */
6667 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6669 return -EINVAL;
6670 }
6671
6672 isFwrRoamEnabled = nla_get_u32(
6673 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6674
6675 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6676
6677 /* Parse and fetch bssid */
6678 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6680 return -EINVAL;
6681 }
6682
6683 memcpy(bssid, nla_data(
6684 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6685 sizeof(bssid));
6686 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6687
6688 //Update roaming
6689 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306690 if (!HAL_STATUS_SUCCESS(status)) {
6691 hddLog(LOGE,
6692 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6693 return -EINVAL;
6694 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306695 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306696 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306697}
6698
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306699static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6700 struct wireless_dev *wdev, const void *data, int data_len)
6701{
6702 int ret = 0;
6703
6704 vos_ssr_protect(__func__);
6705 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6706 vos_ssr_unprotect(__func__);
6707
6708 return ret;
6709}
6710
Sushant Kaushik847890c2015-09-28 16:05:17 +05306711static const struct
6712nla_policy
6713qca_wlan_vendor_get_wifi_info_policy[
6714 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6715 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6716 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6717};
6718
6719
6720/**
6721 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6722 * @wiphy: pointer to wireless wiphy structure.
6723 * @wdev: pointer to wireless_dev structure.
6724 * @data: Pointer to the data to be passed via vendor interface
6725 * @data_len:Length of the data to be passed
6726 *
6727 * This is called when wlan driver needs to send wifi driver related info
6728 * (driver/fw version) to the user space application upon request.
6729 *
6730 * Return: Return the Success or Failure code.
6731 */
6732static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6733 struct wireless_dev *wdev,
6734 const void *data, int data_len)
6735{
6736 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6737 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6738 tSirVersionString version;
6739 uint32 version_len;
6740 uint8 attr;
6741 int status;
6742 struct sk_buff *reply_skb = NULL;
6743
6744 if (VOS_FTM_MODE == hdd_get_conparam()) {
6745 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6746 return -EINVAL;
6747 }
6748
6749 status = wlan_hdd_validate_context(hdd_ctx);
6750 if (0 != status) {
6751 hddLog(LOGE, FL("HDD context is not valid"));
6752 return -EINVAL;
6753 }
6754
6755 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6756 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6757 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6758 return -EINVAL;
6759 }
6760
6761 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6762 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6763 QWLAN_VERSIONSTR);
6764 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6765 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6766 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6767 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6768 hdd_ctx->fw_Version);
6769 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6770 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6771 } else {
6772 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6773 return -EINVAL;
6774 }
6775
6776 version_len = strlen(version);
6777 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6778 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6779 if (!reply_skb) {
6780 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6781 return -ENOMEM;
6782 }
6783
6784 if (nla_put(reply_skb, attr, version_len, version)) {
6785 hddLog(LOGE, FL("nla put fail"));
6786 kfree_skb(reply_skb);
6787 return -EINVAL;
6788 }
6789
6790 return cfg80211_vendor_cmd_reply(reply_skb);
6791}
6792
6793/**
6794 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6795 * @wiphy: pointer to wireless wiphy structure.
6796 * @wdev: pointer to wireless_dev structure.
6797 * @data: Pointer to the data to be passed via vendor interface
6798 * @data_len:Length of the data to be passed
6799 * @data_len: Length of the data received
6800 *
6801 * This function is used to enable or disable the collection of packet
6802 * statistics from the firmware
6803 *
6804 * Return: 0 on success and errno on failure
6805 */
6806
6807static int
6808wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6809 struct wireless_dev *wdev,
6810 const void *data, int data_len)
6811
6812
6813{
6814 int ret = 0;
6815
6816 vos_ssr_protect(__func__);
6817 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6818 wdev, data, data_len);
6819 vos_ssr_unprotect(__func__);
6820
6821 return ret;
6822}
6823
6824
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306825/*
6826 * define short names for the global vendor params
6827 * used by __wlan_hdd_cfg80211_monitor_rssi()
6828 */
6829#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6830#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6831#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6832#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6833#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6834
6835/**---------------------------------------------------------------------------
6836
6837 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6838 monitor start is completed successfully.
6839
6840 \return - None
6841
6842 --------------------------------------------------------------------------*/
6843void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6844{
6845 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6846
6847 if (NULL == pHddCtx)
6848 {
6849 hddLog(VOS_TRACE_LEVEL_ERROR,
6850 "%s: HDD context is NULL",__func__);
6851 return;
6852 }
6853
6854 if (VOS_STATUS_SUCCESS == status)
6855 {
6856 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6857 }
6858 else
6859 {
6860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6861 }
6862
6863 return;
6864}
6865
6866/**---------------------------------------------------------------------------
6867
6868 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6869 stop is completed successfully.
6870
6871 \return - None
6872
6873 --------------------------------------------------------------------------*/
6874void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6875{
6876 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6877
6878 if (NULL == pHddCtx)
6879 {
6880 hddLog(VOS_TRACE_LEVEL_ERROR,
6881 "%s: HDD context is NULL",__func__);
6882 return;
6883 }
6884
6885 if (VOS_STATUS_SUCCESS == status)
6886 {
6887 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6888 }
6889 else
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6892 }
6893
6894 return;
6895}
6896
6897/**
6898 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6899 * @wiphy: Pointer to wireless phy
6900 * @wdev: Pointer to wireless device
6901 * @data: Pointer to data
6902 * @data_len: Data length
6903 *
6904 * Return: 0 on success, negative errno on failure
6905 */
6906
6907static int
6908__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6909 struct wireless_dev *wdev,
6910 const void *data,
6911 int data_len)
6912{
6913 struct net_device *dev = wdev->netdev;
6914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6915 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6916 hdd_station_ctx_t *pHddStaCtx;
6917 struct nlattr *tb[PARAM_MAX + 1];
6918 tpSirRssiMonitorReq pReq;
6919 eHalStatus status;
6920 int ret;
6921 uint32_t control;
6922 static const struct nla_policy policy[PARAM_MAX + 1] = {
6923 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6924 [PARAM_CONTROL] = { .type = NLA_U32 },
6925 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6926 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6927 };
6928
6929 ENTER();
6930
6931 ret = wlan_hdd_validate_context(hdd_ctx);
6932 if (0 != ret) {
6933 return -EINVAL;
6934 }
6935
6936 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6937 hddLog(LOGE, FL("Not in Connected state!"));
6938 return -ENOTSUPP;
6939 }
6940
6941 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6942 hddLog(LOGE, FL("Invalid ATTR"));
6943 return -EINVAL;
6944 }
6945
6946 if (!tb[PARAM_REQUEST_ID]) {
6947 hddLog(LOGE, FL("attr request id failed"));
6948 return -EINVAL;
6949 }
6950
6951 if (!tb[PARAM_CONTROL]) {
6952 hddLog(LOGE, FL("attr control failed"));
6953 return -EINVAL;
6954 }
6955
6956 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6957
6958 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6959 if(NULL == pReq)
6960 {
6961 hddLog(LOGE,
6962 FL("vos_mem_alloc failed "));
6963 return eHAL_STATUS_FAILED_ALLOC;
6964 }
6965 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6966
6967 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6968 pReq->sessionId = pAdapter->sessionId;
6969 pReq->rssiMonitorCbContext = hdd_ctx;
6970 control = nla_get_u32(tb[PARAM_CONTROL]);
6971 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6972
6973 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6974 pReq->requestId, pReq->sessionId, control);
6975
6976 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6977 if (!tb[PARAM_MIN_RSSI]) {
6978 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306979 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306980 }
6981
6982 if (!tb[PARAM_MAX_RSSI]) {
6983 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306984 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306985 }
6986
6987 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6988 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6989 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6990
6991 if (!(pReq->minRssi < pReq->maxRssi)) {
6992 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6993 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306994 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306995 }
6996 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6997 pReq->minRssi, pReq->maxRssi);
6998 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6999
7000 }
7001 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
7002 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
7003 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
7004 }
7005 else {
7006 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307007 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307008 }
7009
7010 if (!HAL_STATUS_SUCCESS(status)) {
7011 hddLog(LOGE,
7012 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307013 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307014 }
7015
7016 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307017fail:
7018 vos_mem_free(pReq);
7019 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307020}
7021
7022/*
7023 * done with short names for the global vendor params
7024 * used by __wlan_hdd_cfg80211_monitor_rssi()
7025 */
7026#undef PARAM_MAX
7027#undef PARAM_CONTROL
7028#undef PARAM_REQUEST_ID
7029#undef PARAM_MAX_RSSI
7030#undef PARAM_MIN_RSSI
7031
7032/**
7033 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7034 * @wiphy: wiphy structure pointer
7035 * @wdev: Wireless device structure pointer
7036 * @data: Pointer to the data received
7037 * @data_len: Length of @data
7038 *
7039 * Return: 0 on success; errno on failure
7040 */
7041static int
7042wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7043 const void *data, int data_len)
7044{
7045 int ret;
7046
7047 vos_ssr_protect(__func__);
7048 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7049 vos_ssr_unprotect(__func__);
7050
7051 return ret;
7052}
7053
7054/**
7055 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7056 * @hddctx: HDD context
7057 * @data: rssi breached event data
7058 *
7059 * This function reads the rssi breached event %data and fill in the skb with
7060 * NL attributes and send up the NL event.
7061 * This callback execute in atomic context and must not invoke any
7062 * blocking calls.
7063 *
7064 * Return: none
7065 */
7066void hdd_rssi_threshold_breached_cb(void *hddctx,
7067 struct rssi_breach_event *data)
7068{
7069 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7070 int status;
7071 struct sk_buff *skb;
7072
7073 ENTER();
7074 status = wlan_hdd_validate_context(pHddCtx);
7075
7076 if (0 != status) {
7077 return;
7078 }
7079
7080 if (!data) {
7081 hddLog(LOGE, FL("data is null"));
7082 return;
7083 }
7084
7085 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7087 NULL,
7088#endif
7089 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7090 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7091 GFP_KERNEL);
7092
7093 if (!skb) {
7094 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7095 return;
7096 }
7097
7098 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7099 data->request_id, data->curr_rssi);
7100 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7101 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7102
7103 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7104 data->request_id) ||
7105 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7106 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7107 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7108 data->curr_rssi)) {
7109 hddLog(LOGE, FL("nla put fail"));
7110 goto fail;
7111 }
7112
7113 cfg80211_vendor_event(skb, GFP_KERNEL);
7114 return;
7115
7116fail:
7117 kfree_skb(skb);
7118 return;
7119}
7120
7121
7122
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307123/**
7124 * __wlan_hdd_cfg80211_setband() - set band
7125 * @wiphy: Pointer to wireless phy
7126 * @wdev: Pointer to wireless device
7127 * @data: Pointer to data
7128 * @data_len: Data length
7129 *
7130 * Return: 0 on success, negative errno on failure
7131 */
7132static int
7133__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7134 struct wireless_dev *wdev,
7135 const void *data,
7136 int data_len)
7137{
7138 struct net_device *dev = wdev->netdev;
7139 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7140 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7141 int ret;
7142 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7143 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7144
7145 ENTER();
7146
7147 ret = wlan_hdd_validate_context(hdd_ctx);
7148 if (0 != ret) {
7149 hddLog(LOGE, FL("HDD context is not valid"));
7150 return ret;
7151 }
7152
7153 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7154 policy)) {
7155 hddLog(LOGE, FL("Invalid ATTR"));
7156 return -EINVAL;
7157 }
7158
7159 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7160 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7161 return -EINVAL;
7162 }
7163
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307164 hdd_ctx->isSetBandByNL = TRUE;
7165 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307166 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307167 hdd_ctx->isSetBandByNL = FALSE;
7168
7169 EXIT();
7170 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307171}
7172
7173/**
7174 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7175 * @wiphy: wiphy structure pointer
7176 * @wdev: Wireless device structure pointer
7177 * @data: Pointer to the data received
7178 * @data_len: Length of @data
7179 *
7180 * Return: 0 on success; errno on failure
7181 */
7182static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7183 struct wireless_dev *wdev,
7184 const void *data,
7185 int data_len)
7186{
7187 int ret = 0;
7188
7189 vos_ssr_protect(__func__);
7190 ret = __wlan_hdd_cfg80211_setband(wiphy,
7191 wdev, data, data_len);
7192 vos_ssr_unprotect(__func__);
7193
7194 return ret;
7195}
7196
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307197#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7198/**
7199 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7200 * @hdd_ctx: HDD context
7201 * @request_id: [input] request id
7202 * @pattern_id: [output] pattern id
7203 *
7204 * This function loops through request id to pattern id array
7205 * if the slot is available, store the request id and return pattern id
7206 * if entry exists, return the pattern id
7207 *
7208 * Return: 0 on success and errno on failure
7209 */
7210static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7211 uint32_t request_id,
7212 uint8_t *pattern_id)
7213{
7214 uint32_t i;
7215
7216 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7217 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7218 {
7219 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7220 {
7221 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7222 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return 0;
7225 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7226 request_id) {
7227 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7228 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7229 return 0;
7230 }
7231 }
7232 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7233 return -EINVAL;
7234}
7235
7236/**
7237 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7238 * @hdd_ctx: HDD context
7239 * @request_id: [input] request id
7240 * @pattern_id: [output] pattern id
7241 *
7242 * This function loops through request id to pattern id array
7243 * reset request id to 0 (slot available again) and
7244 * return pattern id
7245 *
7246 * Return: 0 on success and errno on failure
7247 */
7248static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7249 uint32_t request_id,
7250 uint8_t *pattern_id)
7251{
7252 uint32_t i;
7253
7254 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7255 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7256 {
7257 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7258 {
7259 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7260 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7261 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7262 return 0;
7263 }
7264 }
7265 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7266 return -EINVAL;
7267}
7268
7269
7270/*
7271 * define short names for the global vendor params
7272 * used by __wlan_hdd_cfg80211_offloaded_packets()
7273 */
7274#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7275#define PARAM_REQUEST_ID \
7276 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7277#define PARAM_CONTROL \
7278 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7279#define PARAM_IP_PACKET \
7280 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7281#define PARAM_SRC_MAC_ADDR \
7282 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7283#define PARAM_DST_MAC_ADDR \
7284 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7285#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7286
7287/**
7288 * wlan_hdd_add_tx_ptrn() - add tx pattern
7289 * @adapter: adapter pointer
7290 * @hdd_ctx: hdd context
7291 * @tb: nl attributes
7292 *
7293 * This function reads the NL attributes and forms a AddTxPtrn message
7294 * posts it to SME.
7295 *
7296 */
7297static int
7298wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7299 struct nlattr **tb)
7300{
7301 struct sSirAddPeriodicTxPtrn *add_req;
7302 eHalStatus status;
7303 uint32_t request_id, ret, len;
7304 uint8_t pattern_id = 0;
7305 v_MACADDR_t dst_addr;
7306 uint16_t eth_type = htons(ETH_P_IP);
7307
7308 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7309 {
7310 hddLog(LOGE, FL("Not in Connected state!"));
7311 return -ENOTSUPP;
7312 }
7313
7314 add_req = vos_mem_malloc(sizeof(*add_req));
7315 if (!add_req)
7316 {
7317 hddLog(LOGE, FL("memory allocation failed"));
7318 return -ENOMEM;
7319 }
7320
7321 /* Parse and fetch request Id */
7322 if (!tb[PARAM_REQUEST_ID])
7323 {
7324 hddLog(LOGE, FL("attr request id failed"));
7325 goto fail;
7326 }
7327
7328 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7329 hddLog(LOG1, FL("Request Id: %u"), request_id);
7330 if (request_id == 0)
7331 {
7332 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307333 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307334 }
7335
7336 if (!tb[PARAM_PERIOD])
7337 {
7338 hddLog(LOGE, FL("attr period failed"));
7339 goto fail;
7340 }
7341 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7342 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7343 if (add_req->usPtrnIntervalMs == 0)
7344 {
7345 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7346 goto fail;
7347 }
7348
7349 if (!tb[PARAM_SRC_MAC_ADDR])
7350 {
7351 hddLog(LOGE, FL("attr source mac address failed"));
7352 goto fail;
7353 }
7354 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7355 VOS_MAC_ADDR_SIZE);
7356 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7357 MAC_ADDR_ARRAY(add_req->macAddress));
7358
7359 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7360 VOS_MAC_ADDR_SIZE))
7361 {
7362 hddLog(LOGE,
7363 FL("input src mac address and connected ap bssid are different"));
7364 goto fail;
7365 }
7366
7367 if (!tb[PARAM_DST_MAC_ADDR])
7368 {
7369 hddLog(LOGE, FL("attr dst mac address failed"));
7370 goto fail;
7371 }
7372 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7373 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7374 MAC_ADDR_ARRAY(dst_addr.bytes));
7375
7376 if (!tb[PARAM_IP_PACKET])
7377 {
7378 hddLog(LOGE, FL("attr ip packet failed"));
7379 goto fail;
7380 }
7381 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7382 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7383
7384 if (add_req->ucPtrnSize < 0 ||
7385 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7386 HDD_ETH_HEADER_LEN))
7387 {
7388 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7389 add_req->ucPtrnSize);
7390 goto fail;
7391 }
7392
7393 len = 0;
7394 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7395 len += VOS_MAC_ADDR_SIZE;
7396 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7397 VOS_MAC_ADDR_SIZE);
7398 len += VOS_MAC_ADDR_SIZE;
7399 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7400 len += 2;
7401
7402 /*
7403 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7404 * ------------------------------------------------------------
7405 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7406 * ------------------------------------------------------------
7407 */
7408 vos_mem_copy(&add_req->ucPattern[len],
7409 nla_data(tb[PARAM_IP_PACKET]),
7410 add_req->ucPtrnSize);
7411 add_req->ucPtrnSize += len;
7412
7413 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7414 add_req->ucPattern, add_req->ucPtrnSize);
7415
7416 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7417 if (ret)
7418 {
7419 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7420 goto fail;
7421 }
7422 add_req->ucPtrnId = pattern_id;
7423 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7424
7425 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7426 if (!HAL_STATUS_SUCCESS(status))
7427 {
7428 hddLog(LOGE,
7429 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7430 goto fail;
7431 }
7432
7433 EXIT();
7434 vos_mem_free(add_req);
7435 return 0;
7436
7437fail:
7438 vos_mem_free(add_req);
7439 return -EINVAL;
7440}
7441
7442/**
7443 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7444 * @adapter: adapter pointer
7445 * @hdd_ctx: hdd context
7446 * @tb: nl attributes
7447 *
7448 * This function reads the NL attributes and forms a DelTxPtrn message
7449 * posts it to SME.
7450 *
7451 */
7452static int
7453wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7454 struct nlattr **tb)
7455{
7456 struct sSirDelPeriodicTxPtrn *del_req;
7457 eHalStatus status;
7458 uint32_t request_id, ret;
7459 uint8_t pattern_id = 0;
7460
7461 /* Parse and fetch request Id */
7462 if (!tb[PARAM_REQUEST_ID])
7463 {
7464 hddLog(LOGE, FL("attr request id failed"));
7465 return -EINVAL;
7466 }
7467 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7468 if (request_id == 0)
7469 {
7470 hddLog(LOGE, FL("request_id cannot be zero"));
7471 return -EINVAL;
7472 }
7473
7474 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7475 if (ret)
7476 {
7477 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7478 return -EINVAL;
7479 }
7480
7481 del_req = vos_mem_malloc(sizeof(*del_req));
7482 if (!del_req)
7483 {
7484 hddLog(LOGE, FL("memory allocation failed"));
7485 return -ENOMEM;
7486 }
7487
7488 vos_mem_set(del_req, sizeof(*del_req), 0);
7489 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7490 VOS_MAC_ADDR_SIZE);
7491 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7492 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7493 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7494 request_id, pattern_id, del_req->ucPatternIdBitmap);
7495
7496 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7497 if (!HAL_STATUS_SUCCESS(status))
7498 {
7499 hddLog(LOGE,
7500 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7501 goto fail;
7502 }
7503
7504 EXIT();
7505 vos_mem_free(del_req);
7506 return 0;
7507
7508fail:
7509 vos_mem_free(del_req);
7510 return -EINVAL;
7511}
7512
7513
7514/**
7515 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7516 * @wiphy: Pointer to wireless phy
7517 * @wdev: Pointer to wireless device
7518 * @data: Pointer to data
7519 * @data_len: Data length
7520 *
7521 * Return: 0 on success, negative errno on failure
7522 */
7523static int
7524__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7525 struct wireless_dev *wdev,
7526 const void *data,
7527 int data_len)
7528{
7529 struct net_device *dev = wdev->netdev;
7530 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7531 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7532 struct nlattr *tb[PARAM_MAX + 1];
7533 uint8_t control;
7534 int ret;
7535 static const struct nla_policy policy[PARAM_MAX + 1] =
7536 {
7537 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7538 [PARAM_CONTROL] = { .type = NLA_U32 },
7539 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7540 .len = VOS_MAC_ADDR_SIZE },
7541 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7542 .len = VOS_MAC_ADDR_SIZE },
7543 [PARAM_PERIOD] = { .type = NLA_U32 },
7544 };
7545
7546 ENTER();
7547
7548 ret = wlan_hdd_validate_context(hdd_ctx);
7549 if (0 != ret)
7550 {
7551 hddLog(LOGE, FL("HDD context is not valid"));
7552 return ret;
7553 }
7554
7555 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7556 {
7557 hddLog(LOGE,
7558 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7559 return -ENOTSUPP;
7560 }
7561
7562 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7563 {
7564 hddLog(LOGE, FL("Invalid ATTR"));
7565 return -EINVAL;
7566 }
7567
7568 if (!tb[PARAM_CONTROL])
7569 {
7570 hddLog(LOGE, FL("attr control failed"));
7571 return -EINVAL;
7572 }
7573 control = nla_get_u32(tb[PARAM_CONTROL]);
7574 hddLog(LOG1, FL("Control: %d"), control);
7575
7576 if (control == WLAN_START_OFFLOADED_PACKETS)
7577 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7578 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7579 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7580 else
7581 {
7582 hddLog(LOGE, FL("Invalid control: %d"), control);
7583 return -EINVAL;
7584 }
7585}
7586
7587/*
7588 * done with short names for the global vendor params
7589 * used by __wlan_hdd_cfg80211_offloaded_packets()
7590 */
7591#undef PARAM_MAX
7592#undef PARAM_REQUEST_ID
7593#undef PARAM_CONTROL
7594#undef PARAM_IP_PACKET
7595#undef PARAM_SRC_MAC_ADDR
7596#undef PARAM_DST_MAC_ADDR
7597#undef PARAM_PERIOD
7598
7599/**
7600 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7601 * @wiphy: wiphy structure pointer
7602 * @wdev: Wireless device structure pointer
7603 * @data: Pointer to the data received
7604 * @data_len: Length of @data
7605 *
7606 * Return: 0 on success; errno on failure
7607 */
7608static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7609 struct wireless_dev *wdev,
7610 const void *data,
7611 int data_len)
7612{
7613 int ret = 0;
7614
7615 vos_ssr_protect(__func__);
7616 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7617 wdev, data, data_len);
7618 vos_ssr_unprotect(__func__);
7619
7620 return ret;
7621}
7622#endif
7623
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307624static const struct
7625nla_policy
7626qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307627 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7628 .type = NLA_BINARY,
7629 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307630};
7631
7632/**
7633 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7634 * get link properties like nss, rate flags and operating frequency for
7635 * the connection with the given peer.
7636 * @wiphy: WIPHY structure pointer
7637 * @wdev: Wireless device structure pointer
7638 * @data: Pointer to the data received
7639 * @data_len: Length of the data received
7640 *
7641 * This function return the above link properties on success.
7642 *
7643 * Return: 0 on success and errno on failure
7644 */
7645static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7646 struct wireless_dev *wdev,
7647 const void *data,
7648 int data_len)
7649{
7650 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7651 struct net_device *dev = wdev->netdev;
7652 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7653 hdd_station_ctx_t *hdd_sta_ctx;
7654 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7655 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7656 uint32_t sta_id;
7657 struct sk_buff *reply_skb;
7658 uint32_t rate_flags = 0;
7659 uint8_t nss;
7660 uint8_t final_rate_flags = 0;
7661 uint32_t freq;
7662 v_CONTEXT_t pVosContext = NULL;
7663 ptSapContext pSapCtx = NULL;
7664
7665 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7667 return -EINVAL;
7668 }
7669
7670 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7671 qca_wlan_vendor_attr_policy)) {
7672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7673 return -EINVAL;
7674 }
7675
7676 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7677 hddLog(VOS_TRACE_LEVEL_ERROR,
7678 FL("Attribute peerMac not provided for mode=%d"),
7679 adapter->device_mode);
7680 return -EINVAL;
7681 }
7682
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307683 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7684 hddLog(VOS_TRACE_LEVEL_ERROR,
7685 FL("Attribute peerMac is invalid=%d"),
7686 adapter->device_mode);
7687 return -EINVAL;
7688 }
7689
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307690 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7691 sizeof(peer_mac));
7692 hddLog(VOS_TRACE_LEVEL_INFO,
7693 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7694 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7695
7696 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7697 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7698 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7699 if ((hdd_sta_ctx->conn_info.connState !=
7700 eConnectionState_Associated) ||
7701 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7702 VOS_MAC_ADDRESS_LEN)) {
7703 hddLog(VOS_TRACE_LEVEL_ERROR,
7704 FL("Not Associated to mac "MAC_ADDRESS_STR),
7705 MAC_ADDR_ARRAY(peer_mac));
7706 return -EINVAL;
7707 }
7708
7709 nss = 1; //pronto supports only one spatial stream
7710 freq = vos_chan_to_freq(
7711 hdd_sta_ctx->conn_info.operationChannel);
7712 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7713
7714 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7715 adapter->device_mode == WLAN_HDD_SOFTAP) {
7716
7717 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7718 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7719 if(pSapCtx == NULL){
7720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7721 FL("psapCtx is NULL"));
7722 return -ENOENT;
7723 }
7724
7725
7726 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7727 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7728 !vos_is_macaddr_broadcast(
7729 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7730 vos_mem_compare(
7731 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7732 peer_mac, VOS_MAC_ADDRESS_LEN))
7733 break;
7734 }
7735
7736 if (WLAN_MAX_STA_COUNT == sta_id) {
7737 hddLog(VOS_TRACE_LEVEL_ERROR,
7738 FL("No active peer with mac="MAC_ADDRESS_STR),
7739 MAC_ADDR_ARRAY(peer_mac));
7740 return -EINVAL;
7741 }
7742
7743 nss = 1; //pronto supports only one spatial stream
7744 freq = vos_chan_to_freq(
7745 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7746 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7747 } else {
7748 hddLog(VOS_TRACE_LEVEL_ERROR,
7749 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7750 MAC_ADDR_ARRAY(peer_mac));
7751 return -EINVAL;
7752 }
7753
7754 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7755 if (rate_flags & eHAL_TX_RATE_VHT80) {
7756 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7758 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307759 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307760#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307761 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7762 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307763#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7764 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307765 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307766#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7768 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7769 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7770 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307771#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7772 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307773 if (rate_flags & eHAL_TX_RATE_HT40)
7774 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307775#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307776 }
7777
7778 if (rate_flags & eHAL_TX_RATE_SGI) {
7779 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7780 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7781 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7782 }
7783 }
7784
7785 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7786 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7787
7788 if (NULL == reply_skb) {
7789 hddLog(VOS_TRACE_LEVEL_ERROR,
7790 FL("getLinkProperties: skb alloc failed"));
7791 return -EINVAL;
7792 }
7793
7794 if (nla_put_u8(reply_skb,
7795 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7796 nss) ||
7797 nla_put_u8(reply_skb,
7798 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7799 final_rate_flags) ||
7800 nla_put_u32(reply_skb,
7801 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7802 freq)) {
7803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7804 kfree_skb(reply_skb);
7805 return -EINVAL;
7806 }
7807
7808 return cfg80211_vendor_cmd_reply(reply_skb);
7809}
7810
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307811#define BEACON_MISS_THRESH_2_4 \
7812 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7813#define BEACON_MISS_THRESH_5_0 \
7814 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307815#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7816#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7817#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7818#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307819#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7820 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307821
7822/**
7823 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7824 * vendor command
7825 *
7826 * @wiphy: wiphy device pointer
7827 * @wdev: wireless device pointer
7828 * @data: Vendor command data buffer
7829 * @data_len: Buffer length
7830 *
7831 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7832 *
7833 * Return: EOK or other error codes.
7834 */
7835
7836static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7837 struct wireless_dev *wdev,
7838 const void *data,
7839 int data_len)
7840{
7841 struct net_device *dev = wdev->netdev;
7842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7843 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7844 hdd_station_ctx_t *pHddStaCtx;
7845 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7846 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307847 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307848 eHalStatus status;
7849 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307850 uint8_t hb_thresh_val;
7851
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307852 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7853 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7854 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307855 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7856 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7857 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307858 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7859 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307860 };
7861
7862 ENTER();
7863
7864 if (VOS_FTM_MODE == hdd_get_conparam()) {
7865 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7866 return -EINVAL;
7867 }
7868
7869 ret_val = wlan_hdd_validate_context(pHddCtx);
7870 if (ret_val) {
7871 return ret_val;
7872 }
7873
7874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7875
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307876 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7877 hddLog(LOGE, FL("Invalid ATTR"));
7878 return -EINVAL;
7879 }
7880
7881 /* check the Wifi Capability */
7882 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7883 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7884 {
7885 hddLog(VOS_TRACE_LEVEL_ERROR,
7886 FL("WIFICONFIG not supported by Firmware"));
7887 return -EINVAL;
7888 }
7889
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307890 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7891 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7892 modifyRoamParamsReq.value =
7893 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7894
7895 if (eHAL_STATUS_SUCCESS !=
7896 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7897 {
7898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7899 ret_val = -EINVAL;
7900 }
7901 return ret_val;
7902 }
7903
7904 /* Moved this down in order to provide provision to set beacon
7905 * miss penalty count irrespective of connection state.
7906 */
7907 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7908 hddLog(LOGE, FL("Not in Connected state!"));
7909 return -ENOTSUPP;
7910 }
7911
7912 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307913
7914 if (!pReq) {
7915 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7916 "%s: Not able to allocate memory for tSetWifiConfigParams",
7917 __func__);
7918 return eHAL_STATUS_E_MALLOC_FAILED;
7919 }
7920
7921 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7922
7923 pReq->sessionId = pAdapter->sessionId;
7924 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7925
7926 if (tb[PARAM_MODULATED_DTIM]) {
7927 pReq->paramValue = nla_get_u32(
7928 tb[PARAM_MODULATED_DTIM]);
7929 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7930 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307931 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307932 hdd_set_pwrparams(pHddCtx);
7933 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7934 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7935
7936 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7937 iw_full_power_cbfn, pAdapter,
7938 eSME_FULL_PWR_NEEDED_BY_HDD);
7939 }
7940 else
7941 {
7942 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7943 }
7944 }
7945
7946 if (tb[PARAM_STATS_AVG_FACTOR]) {
7947 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7948 pReq->paramValue = nla_get_u16(
7949 tb[PARAM_STATS_AVG_FACTOR]);
7950 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7951 pReq->paramType, pReq->paramValue);
7952 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7953
7954 if (eHAL_STATUS_SUCCESS != status)
7955 {
7956 vos_mem_free(pReq);
7957 pReq = NULL;
7958 ret_val = -EPERM;
7959 return ret_val;
7960 }
7961 }
7962
7963
7964 if (tb[PARAM_GUARD_TIME]) {
7965 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7966 pReq->paramValue = nla_get_u32(
7967 tb[PARAM_GUARD_TIME]);
7968 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7969 pReq->paramType, pReq->paramValue);
7970 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7971
7972 if (eHAL_STATUS_SUCCESS != status)
7973 {
7974 vos_mem_free(pReq);
7975 pReq = NULL;
7976 ret_val = -EPERM;
7977 return ret_val;
7978 }
7979
7980 }
7981
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307982 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7983 hb_thresh_val = nla_get_u8(
7984 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7985
7986 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7987 hb_thresh_val);
7988 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7989 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7990 NULL, eANI_BOOLEAN_FALSE);
7991
7992 status = sme_update_hb_threshold(
7993 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7994 WNI_CFG_HEART_BEAT_THRESHOLD,
7995 hb_thresh_val, eCSR_BAND_24);
7996 if (eHAL_STATUS_SUCCESS != status) {
7997 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7998 vos_mem_free(pReq);
7999 pReq = NULL;
8000 return -EPERM;
8001 }
8002 }
8003
8004 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8005 hb_thresh_val = nla_get_u8(
8006 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8007
8008 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %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_5G);
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
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308026 EXIT();
8027 return ret_val;
8028}
8029
8030/**
8031 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8032 * vendor command
8033 *
8034 * @wiphy: wiphy device pointer
8035 * @wdev: wireless device pointer
8036 * @data: Vendor command data buffer
8037 * @data_len: Buffer length
8038 *
8039 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8040 *
8041 * Return: EOK or other error codes.
8042 */
8043static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8044 struct wireless_dev *wdev,
8045 const void *data,
8046 int data_len)
8047{
8048 int ret;
8049
8050 vos_ssr_protect(__func__);
8051 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8052 data, data_len);
8053 vos_ssr_unprotect(__func__);
8054
8055 return ret;
8056}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308057
8058/*
8059 * define short names for the global vendor params
8060 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8061 */
8062#define STATS_SET_INVALID \
8063 QCA_ATTR_NUD_STATS_SET_INVALID
8064#define STATS_SET_START \
8065 QCA_ATTR_NUD_STATS_SET_START
8066#define STATS_GW_IPV4 \
8067 QCA_ATTR_NUD_STATS_GW_IPV4
8068#define STATS_SET_MAX \
8069 QCA_ATTR_NUD_STATS_SET_MAX
8070
8071const struct nla_policy
8072qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8073{
8074 [STATS_SET_START] = {.type = NLA_FLAG },
8075 [STATS_GW_IPV4] = {.type = NLA_U32 },
8076};
8077
8078/**
8079 * hdd_set_nud_stats_cb() - hdd callback api to get status
8080 * @data: pointer to adapter
8081 * @rsp: status
8082 *
8083 * Return: None
8084 */
8085static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8086{
8087
8088 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8089
8090 if (NULL == adapter)
8091 return;
8092
8093 if (VOS_STATUS_SUCCESS == rsp) {
8094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8095 "%s success received STATS_SET_START", __func__);
8096 } else {
8097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8098 "%s STATS_SET_START Failed!!", __func__);
8099 }
8100 return;
8101}
8102
8103/**
8104 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8105 * @wiphy: pointer to wireless wiphy structure.
8106 * @wdev: pointer to wireless_dev structure.
8107 * @data: pointer to apfind configuration data.
8108 * @data_len: the length in byte of apfind data.
8109 *
8110 * This is called when wlan driver needs to send arp stats to
8111 * firmware.
8112 *
8113 * Return: An error code or 0 on success.
8114 */
8115static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8116 struct wireless_dev *wdev,
8117 const void *data, int data_len)
8118{
8119 struct nlattr *tb[STATS_SET_MAX + 1];
8120 struct net_device *dev = wdev->netdev;
8121 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8122 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308123 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308124 setArpStatsParams arp_stats_params;
8125 int err = 0;
8126
8127 ENTER();
8128
8129 err = wlan_hdd_validate_context(hdd_ctx);
8130 if (0 != err)
8131 return err;
8132
8133 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8136 return -EINVAL;
8137 }
8138
8139 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8140 qca_wlan_vendor_set_nud_stats);
8141 if (err)
8142 {
8143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8144 "%s STATS_SET_START ATTR", __func__);
8145 return err;
8146 }
8147
8148 if (tb[STATS_SET_START])
8149 {
8150 if (!tb[STATS_GW_IPV4]) {
8151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8152 "%s STATS_SET_START CMD", __func__);
8153 return -EINVAL;
8154 }
8155 arp_stats_params.flag = true;
8156 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8157 } else {
8158 arp_stats_params.flag = false;
8159 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308160 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8162 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308163 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8164 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308165
8166 arp_stats_params.pkt_type = 1; // ARP packet type
8167
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308168 if (arp_stats_params.flag) {
8169 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8170 WLANTL_SetARPFWDatapath(pVosContext, true);
8171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8172 "%s Set FW in data path for ARP with tgt IP :%d",
8173 __func__, hdd_ctx->track_arp_ip);
8174 }
8175 else {
8176 WLANTL_SetARPFWDatapath(pVosContext, false);
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8178 "%s Remove FW from data path", __func__);
8179 }
8180
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308181 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8182 arp_stats_params.data_ctx = adapter;
8183
8184 if (eHAL_STATUS_SUCCESS !=
8185 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8187 "%s STATS_SET_START CMD Failed!!", __func__);
8188 return -EINVAL;
8189 }
8190
8191 EXIT();
8192
8193 return err;
8194}
8195
8196/**
8197 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8198 * @wiphy: pointer to wireless wiphy structure.
8199 * @wdev: pointer to wireless_dev structure.
8200 * @data: pointer to apfind configuration data.
8201 * @data_len: the length in byte of apfind data.
8202 *
8203 * This is called when wlan driver needs to send arp stats to
8204 * firmware.
8205 *
8206 * Return: An error code or 0 on success.
8207 */
8208static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8209 struct wireless_dev *wdev,
8210 const void *data, int data_len)
8211{
8212 int ret;
8213
8214 vos_ssr_protect(__func__);
8215 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8216 vos_ssr_unprotect(__func__);
8217
8218 return ret;
8219}
8220#undef STATS_SET_INVALID
8221#undef STATS_SET_START
8222#undef STATS_GW_IPV4
8223#undef STATS_SET_MAX
8224
8225/*
8226 * define short names for the global vendor params
8227 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8228 */
8229#define STATS_GET_INVALID \
8230 QCA_ATTR_NUD_STATS_SET_INVALID
8231#define COUNT_FROM_NETDEV \
8232 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8233#define COUNT_TO_LOWER_MAC \
8234 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8235#define RX_COUNT_BY_LOWER_MAC \
8236 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8237#define COUNT_TX_SUCCESS \
8238 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8239#define RSP_RX_COUNT_BY_LOWER_MAC \
8240 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8241#define RSP_RX_COUNT_BY_UPPER_MAC \
8242 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8243#define RSP_COUNT_TO_NETDEV \
8244 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8245#define RSP_COUNT_OUT_OF_ORDER_DROP \
8246 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8247#define AP_LINK_ACTIVE \
8248 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8249#define AP_LINK_DAD \
8250 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8251#define STATS_GET_MAX \
8252 QCA_ATTR_NUD_STATS_GET_MAX
8253
8254const struct nla_policy
8255qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8256{
8257 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8258 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8259 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8260 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8261 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8262 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8263 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8264 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8265 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8266 [AP_LINK_DAD] = {.type = NLA_FLAG },
8267};
8268
8269static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8270{
8271
8272 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308273 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308274 struct hdd_nud_stats_context *context;
8275 int status;
8276
8277 ENTER();
8278
8279 if (NULL == adapter)
8280 return;
8281
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308282 if (!rsp) {
8283 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308284 return;
8285 }
8286
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308287 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8288 status = wlan_hdd_validate_context(hdd_ctx);
8289 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308290 return;
8291 }
8292
8293 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8294 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8295 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8296 adapter->dad |= rsp->dad;
8297
8298 spin_lock(&hdd_context_lock);
8299 context = &hdd_ctx->nud_stats_context;
8300 complete(&context->response_event);
8301 spin_unlock(&hdd_context_lock);
8302
8303 return;
8304}
8305static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8306 struct wireless_dev *wdev,
8307 const void *data, int data_len)
8308{
8309 int err = 0;
8310 unsigned long rc;
8311 struct hdd_nud_stats_context *context;
8312 struct net_device *dev = wdev->netdev;
8313 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8314 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8315 getArpStatsParams arp_stats_params;
8316 struct sk_buff *skb;
8317
8318 ENTER();
8319
8320 err = wlan_hdd_validate_context(hdd_ctx);
8321 if (0 != err)
8322 return err;
8323
8324 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8325 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8326 arp_stats_params.data_ctx = adapter;
8327
8328 spin_lock(&hdd_context_lock);
8329 context = &hdd_ctx->nud_stats_context;
8330 INIT_COMPLETION(context->response_event);
8331 spin_unlock(&hdd_context_lock);
8332
8333 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8335 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8336 return -EINVAL;
8337 }
8338
8339 if (eHAL_STATUS_SUCCESS !=
8340 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8342 "%s STATS_SET_START CMD Failed!!", __func__);
8343 return -EINVAL;
8344 }
8345
8346 rc = wait_for_completion_timeout(&context->response_event,
8347 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8348 if (!rc)
8349 {
8350 hddLog(LOGE,
8351 FL("Target response timed out request "));
8352 return -ETIMEDOUT;
8353 }
8354
8355 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8356 WLAN_NUD_STATS_LEN);
8357 if (!skb)
8358 {
8359 hddLog(VOS_TRACE_LEVEL_ERROR,
8360 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8361 __func__);
8362 return -ENOMEM;
8363 }
8364
8365 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8366 adapter->hdd_stats.hddArpStats.txCount) ||
8367 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8368 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8369 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8370 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8371 nla_put_u16(skb, COUNT_TX_SUCCESS,
8372 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8373 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8374 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8375 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8376 adapter->hdd_stats.hddArpStats.rxCount) ||
8377 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8378 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8379 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8380 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8381 hddLog(LOGE, FL("nla put fail"));
8382 kfree_skb(skb);
8383 return -EINVAL;
8384 }
8385 if (adapter->con_status)
8386 nla_put_flag(skb, AP_LINK_ACTIVE);
8387 if (adapter->dad)
8388 nla_put_flag(skb, AP_LINK_DAD);
8389
8390 cfg80211_vendor_cmd_reply(skb);
8391 return err;
8392}
8393
8394static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8395 struct wireless_dev *wdev,
8396 const void *data, int data_len)
8397{
8398 int ret;
8399
8400 vos_ssr_protect(__func__);
8401 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8402 vos_ssr_unprotect(__func__);
8403
8404 return ret;
8405}
8406
8407#undef QCA_ATTR_NUD_STATS_SET_INVALID
8408#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8409#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8410#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8411#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8412#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8413#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8414#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8415#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8416#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8417#undef QCA_ATTR_NUD_STATS_GET_MAX
8418
8419
8420
Kapil Guptaee33bf12016-12-20 18:27:37 +05308421#ifdef WLAN_FEATURE_APFIND
8422/**
8423 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8424 * @wiphy: pointer to wireless wiphy structure.
8425 * @wdev: pointer to wireless_dev structure.
8426 * @data: pointer to apfind configuration data.
8427 * @data_len: the length in byte of apfind data.
8428 *
8429 * This is called when wlan driver needs to send APFIND configurations to
8430 * firmware.
8431 *
8432 * Return: An error code or 0 on success.
8433 */
8434static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8435 struct wireless_dev *wdev,
8436 const void *data, int data_len)
8437{
8438 struct sme_ap_find_request_req apfind_req;
8439 VOS_STATUS status;
8440 int ret_val;
8441 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8442
8443 ENTER();
8444
8445 ret_val = wlan_hdd_validate_context(hdd_ctx);
8446 if (ret_val)
8447 return ret_val;
8448
8449 if (VOS_FTM_MODE == hdd_get_conparam()) {
8450 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8451 return -EPERM;
8452 }
8453
8454 apfind_req.request_data_len = data_len;
8455 apfind_req.request_data = data;
8456
8457 status = sme_apfind_set_cmd(&apfind_req);
8458 if (VOS_STATUS_SUCCESS != status) {
8459 ret_val = -EIO;
8460 }
8461 return ret_val;
8462}
8463
8464/**
8465 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8466 * @wiphy: pointer to wireless wiphy structure.
8467 * @wdev: pointer to wireless_dev structure.
8468 * @data: pointer to apfind configuration data.
8469 * @data_len: the length in byte of apfind data.
8470 *
8471 * This is called when wlan driver needs to send APFIND configurations to
8472 * firmware.
8473 *
8474 * Return: An error code or 0 on success.
8475 */
8476static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8477 struct wireless_dev *wdev,
8478 const void *data, int data_len)
8479{
8480 int ret;
8481
8482 vos_ssr_protect(__func__);
8483 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8484 vos_ssr_unprotect(__func__);
8485
8486 return ret;
8487}
8488#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308489const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8490{
Mukul Sharma2a271632014-10-13 14:59:01 +05308491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV |
8496 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308497 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308498 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308499
8500 {
8501 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8502 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8503 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8504 WIPHY_VENDOR_CMD_NEED_NETDEV |
8505 WIPHY_VENDOR_CMD_NEED_RUNNING,
8506 .doit = wlan_hdd_cfg80211_nan_request
8507 },
8508
Sunil Duttc69bccb2014-05-26 21:30:20 +05308509#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8514 WIPHY_VENDOR_CMD_NEED_NETDEV |
8515 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308516 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308517 },
8518
8519 {
8520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8523 WIPHY_VENDOR_CMD_NEED_NETDEV |
8524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308526 },
8527
8528 {
8529 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8530 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8531 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8532 WIPHY_VENDOR_CMD_NEED_NETDEV |
8533 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308534 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308535 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308536#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308537#ifdef WLAN_FEATURE_EXTSCAN
8538 {
8539 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8540 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8541 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8542 WIPHY_VENDOR_CMD_NEED_NETDEV |
8543 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308544 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308545 },
8546 {
8547 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8548 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8549 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8550 WIPHY_VENDOR_CMD_NEED_NETDEV |
8551 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308552 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308553 },
8554 {
8555 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8556 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8557 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8558 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308559 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308560 },
8561 {
8562 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8563 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8564 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8565 WIPHY_VENDOR_CMD_NEED_NETDEV |
8566 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308567 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308568 },
8569 {
8570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8573 WIPHY_VENDOR_CMD_NEED_NETDEV |
8574 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308575 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308576 },
8577 {
8578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8581 WIPHY_VENDOR_CMD_NEED_NETDEV |
8582 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308583 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584 },
8585 {
8586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8589 WIPHY_VENDOR_CMD_NEED_NETDEV |
8590 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308591 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308592 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308593#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308594/*EXT TDLS*/
8595 {
8596 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8597 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8598 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8599 WIPHY_VENDOR_CMD_NEED_NETDEV |
8600 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308601 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308602 },
8603 {
8604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8607 WIPHY_VENDOR_CMD_NEED_NETDEV |
8608 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308609 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308610 },
8611 {
8612 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8613 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8614 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8615 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308616 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308617 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308618 {
8619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8622 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308623 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308624 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308625 {
8626 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8627 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8628 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8629 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308630 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308631 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308632 {
8633 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8634 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8635 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8636 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308637 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308638 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308639 {
8640 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8641 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8642 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8643 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308644 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308645 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308646 {
8647 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308648 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8649 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8650 WIPHY_VENDOR_CMD_NEED_NETDEV |
8651 WIPHY_VENDOR_CMD_NEED_RUNNING,
8652 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8653 },
8654 {
8655 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308656 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8657 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8658 WIPHY_VENDOR_CMD_NEED_NETDEV |
8659 WIPHY_VENDOR_CMD_NEED_RUNNING,
8660 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308661 },
8662 {
8663 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8664 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8665 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8666 WIPHY_VENDOR_CMD_NEED_NETDEV,
8667 .doit = wlan_hdd_cfg80211_wifi_logger_start
8668 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308669 {
8670 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8671 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8672 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8673 WIPHY_VENDOR_CMD_NEED_NETDEV|
8674 WIPHY_VENDOR_CMD_NEED_RUNNING,
8675 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308676 },
8677 {
8678 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8679 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8680 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8681 WIPHY_VENDOR_CMD_NEED_NETDEV |
8682 WIPHY_VENDOR_CMD_NEED_RUNNING,
8683 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308684 },
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
8691 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308692 },
8693#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8694 {
8695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8698 WIPHY_VENDOR_CMD_NEED_NETDEV |
8699 WIPHY_VENDOR_CMD_NEED_RUNNING,
8700 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308701 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308702#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308703 {
8704 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8705 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8706 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8707 WIPHY_VENDOR_CMD_NEED_NETDEV |
8708 WIPHY_VENDOR_CMD_NEED_RUNNING,
8709 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308710 },
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV |
8716 WIPHY_VENDOR_CMD_NEED_RUNNING,
8717 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308718 },
8719#ifdef WLAN_FEATURE_APFIND
8720 {
8721 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8722 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8723 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8724 WIPHY_VENDOR_CMD_NEED_NETDEV,
8725 .doit = wlan_hdd_cfg80211_apfind_cmd
8726 },
8727#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308728 {
8729 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8730 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8731 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8732 WIPHY_VENDOR_CMD_NEED_NETDEV |
8733 WIPHY_VENDOR_CMD_NEED_RUNNING,
8734 .doit = wlan_hdd_cfg80211_set_nud_stats
8735 },
8736 {
8737 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8738 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8739 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8740 WIPHY_VENDOR_CMD_NEED_NETDEV |
8741 WIPHY_VENDOR_CMD_NEED_RUNNING,
8742 .doit = wlan_hdd_cfg80211_get_nud_stats
8743 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308744 {
8745 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8746 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8747 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8748 WIPHY_VENDOR_CMD_NEED_NETDEV |
8749 WIPHY_VENDOR_CMD_NEED_RUNNING,
8750 .doit = hdd_cfg80211_get_station_cmd
8751 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308752};
8753
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008754/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308755static const
8756struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008757{
8758#ifdef FEATURE_WLAN_CH_AVOID
8759 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308760 .vendor_id = QCA_NL80211_VENDOR_ID,
8761 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008762 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308763#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8764#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8765 {
8766 /* Index = 1*/
8767 .vendor_id = QCA_NL80211_VENDOR_ID,
8768 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8769 },
8770 {
8771 /* Index = 2*/
8772 .vendor_id = QCA_NL80211_VENDOR_ID,
8773 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8774 },
8775 {
8776 /* Index = 3*/
8777 .vendor_id = QCA_NL80211_VENDOR_ID,
8778 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8779 },
8780 {
8781 /* Index = 4*/
8782 .vendor_id = QCA_NL80211_VENDOR_ID,
8783 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8784 },
8785 {
8786 /* Index = 5*/
8787 .vendor_id = QCA_NL80211_VENDOR_ID,
8788 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8789 },
8790 {
8791 /* Index = 6*/
8792 .vendor_id = QCA_NL80211_VENDOR_ID,
8793 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8794 },
8795#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308796#ifdef WLAN_FEATURE_EXTSCAN
8797 {
8798 .vendor_id = QCA_NL80211_VENDOR_ID,
8799 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8800 },
8801 {
8802 .vendor_id = QCA_NL80211_VENDOR_ID,
8803 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8804 },
8805 {
8806 .vendor_id = QCA_NL80211_VENDOR_ID,
8807 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8808 },
8809 {
8810 .vendor_id = QCA_NL80211_VENDOR_ID,
8811 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8812 },
8813 {
8814 .vendor_id = QCA_NL80211_VENDOR_ID,
8815 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8816 },
8817 {
8818 .vendor_id = QCA_NL80211_VENDOR_ID,
8819 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8820 },
8821 {
8822 .vendor_id = QCA_NL80211_VENDOR_ID,
8823 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8824 },
8825 {
8826 .vendor_id = QCA_NL80211_VENDOR_ID,
8827 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8828 },
8829 {
8830 .vendor_id = QCA_NL80211_VENDOR_ID,
8831 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8832 },
8833 {
8834 .vendor_id = QCA_NL80211_VENDOR_ID,
8835 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8836 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308837#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308838/*EXT TDLS*/
8839 {
8840 .vendor_id = QCA_NL80211_VENDOR_ID,
8841 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8842 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308843 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8844 .vendor_id = QCA_NL80211_VENDOR_ID,
8845 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8846 },
8847
Srinivas Dasari030bad32015-02-18 23:23:54 +05308848
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308849 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308850 .vendor_id = QCA_NL80211_VENDOR_ID,
8851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8852 },
8853
Sushant Kaushik084f6592015-09-10 13:11:56 +05308854 {
8855 .vendor_id = QCA_NL80211_VENDOR_ID,
8856 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308857 },
8858 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8859 .vendor_id = QCA_NL80211_VENDOR_ID,
8860 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8861 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308862 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8863 .vendor_id = QCA_NL80211_VENDOR_ID,
8864 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8865 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308866 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8867 .vendor_id = QCA_NL80211_VENDOR_ID,
8868 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8869 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308870 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8871 .vendor_id = QCA_NL80211_VENDOR_ID,
8872 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8873 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308874 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8875 .vendor_id = QCA_NL80211_VENDOR_ID,
8876 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8877 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008878};
8879
Jeff Johnson295189b2012-06-20 16:38:30 -07008880/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308881 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308882 * This function is called by hdd_wlan_startup()
8883 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308884 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008885 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308886struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008887{
8888 struct wiphy *wiphy;
8889 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308890 /*
8891 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 */
8893 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8894
8895 if (!wiphy)
8896 {
8897 /* Print error and jump into err label and free the memory */
8898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8899 return NULL;
8900 }
8901
Sunil Duttc69bccb2014-05-26 21:30:20 +05308902
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 return wiphy;
8904}
8905
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308906#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8907 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8908/**
8909 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8910 * @wiphy: pointer to wiphy
8911 * @config: pointer to config
8912 *
8913 * Return: None
8914 */
8915static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8916 hdd_config_t *config)
8917{
8918 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8919 if (config->max_sched_scan_plan_interval)
8920 wiphy->max_sched_scan_plan_interval =
8921 config->max_sched_scan_plan_interval;
8922 if (config->max_sched_scan_plan_iterations)
8923 wiphy->max_sched_scan_plan_iterations =
8924 config->max_sched_scan_plan_iterations;
8925}
8926#else
8927static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8928 hdd_config_t *config)
8929{
8930}
8931#endif
8932
Jeff Johnson295189b2012-06-20 16:38:30 -07008933/*
8934 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308935 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 * private ioctl to change the band value
8937 */
8938int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8939{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308940 int i, j;
8941 eNVChannelEnabledType channelEnabledState;
8942
Jeff Johnsone7245742012-09-05 17:12:55 -07008943 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308944
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308945 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308947
8948 if (NULL == wiphy->bands[i])
8949 {
8950 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8951 __func__, i);
8952 continue;
8953 }
8954
8955 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8956 {
8957 struct ieee80211_supported_band *band = wiphy->bands[i];
8958
8959 channelEnabledState = vos_nv_getChannelEnabledState(
8960 band->channels[j].hw_value);
8961
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308962 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308963 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308964 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308965 continue;
8966 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308967 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308968 {
8969 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8970 continue;
8971 }
8972
8973 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8974 NV_CHANNEL_INVALID == channelEnabledState)
8975 {
8976 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8977 }
8978 else if (NV_CHANNEL_DFS == channelEnabledState)
8979 {
8980 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8981 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8982 }
8983 else
8984 {
8985 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8986 |IEEE80211_CHAN_RADAR);
8987 }
8988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 }
8990 return 0;
8991}
8992/*
8993 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308994 * This function is called by hdd_wlan_startup()
8995 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 * This function is used to initialize and register wiphy structure.
8997 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308998int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 struct wiphy *wiphy,
9000 hdd_config_t *pCfg
9001 )
9002{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309003 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9005
Jeff Johnsone7245742012-09-05 17:12:55 -07009006 ENTER();
9007
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 /* Now bind the underlying wlan device with wiphy */
9009 set_wiphy_dev(wiphy, dev);
9010
9011 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009012
Kiet Lam6c583332013-10-14 05:37:09 +05309013#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009014 /* the flag for the other case would be initialzed in
9015 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9017 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9018#else
Amar Singhal0a402232013-10-11 20:57:16 -07009019 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309020#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309021#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009022
Amar Singhalfddc28c2013-09-05 13:03:40 -07009023 /* This will disable updating of NL channels from passive to
9024 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9026 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9027#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009028 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309029#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009030
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309031#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9032 wiphy->wowlan = &wowlan_support_cfg80211_init;
9033#else
9034 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
9035 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9036 wiphy->wowlan.pattern_min_len = 1;
9037 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9038#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009039
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009040#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009041 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9042 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9043 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009044 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309045#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309046 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309047#else
9048 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9049#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009050#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009051
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009052#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009053 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009054#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009055 || pCfg->isFastRoamIniFeatureEnabled
9056#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009057#ifdef FEATURE_WLAN_ESE
9058 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009059#endif
9060 )
9061 {
9062 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9063 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009064#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009065#ifdef FEATURE_WLAN_TDLS
9066 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9067 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9068#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309069#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309070 if (pCfg->configPNOScanSupport)
9071 {
9072 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9073 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9074 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9075 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9076 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309077#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009078
Abhishek Singh10d85972015-04-17 10:27:23 +05309079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9080 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9081#endif
9082
Amar Singhalfddc28c2013-09-05 13:03:40 -07009083#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009084 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9085 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009086 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009087 driver need to determine what to do with both
9088 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009089
9090 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009091#else
9092 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009093#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009094
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309095 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9096
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309097 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009098
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309099 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9100
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309102 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9103 | BIT(NL80211_IFTYPE_ADHOC)
9104 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9105 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309106 | BIT(NL80211_IFTYPE_AP)
9107 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009108
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309109 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009110 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9112 if( pCfg->enableMCC )
9113 {
9114 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309115 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009116
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309117 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309118 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009119
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309120 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309121 wiphy->iface_combinations = wlan_hdd_iface_combination;
9122 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009123#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309124 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009125
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 /* Before registering we need to update the ht capabilitied based
9127 * on ini values*/
9128 if( !pCfg->ShortGI20MhzEnable )
9129 {
9130 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9131 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009132 }
9133
9134 if( !pCfg->ShortGI40MhzEnable )
9135 {
9136 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9137 }
9138
9139 if( !pCfg->nChannelBondingMode5GHz )
9140 {
9141 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9142 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309143 /*
9144 * In case of static linked driver at the time of driver unload,
9145 * module exit doesn't happens. Module cleanup helps in cleaning
9146 * of static memory.
9147 * If driver load happens statically, at the time of driver unload,
9148 * wiphy flags don't get reset because of static memory.
9149 * It's better not to store channel in static memory.
9150 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309151 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9152 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309153 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309154 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309155 {
9156 hddLog(VOS_TRACE_LEVEL_ERROR,
9157 FL("Not enough memory to allocate channels"));
9158 return -ENOMEM;
9159 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309160 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309161 &hdd_channels_2_4_GHZ[0],
9162 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009163
Agrawal Ashish97dec502015-11-26 20:20:58 +05309164 if (true == hdd_is_5g_supported(pHddCtx))
9165 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309166 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9167 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309168 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309169 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309170 {
9171 hddLog(VOS_TRACE_LEVEL_ERROR,
9172 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309173 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9174 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309175 return -ENOMEM;
9176 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309177 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309178 &hdd_channels_5_GHZ[0],
9179 sizeof(hdd_channels_5_GHZ));
9180 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309181
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309182 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309183 {
9184
9185 if (NULL == wiphy->bands[i])
9186 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309187 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309188 __func__, i);
9189 continue;
9190 }
9191
9192 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9193 {
9194 struct ieee80211_supported_band *band = wiphy->bands[i];
9195
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309196 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309197 {
9198 // Enable social channels for P2P
9199 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9200 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9201 else
9202 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9203 continue;
9204 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309205 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309206 {
9207 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9208 continue;
9209 }
9210 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009211 }
9212 /*Initialise the supported cipher suite details*/
9213 wiphy->cipher_suites = hdd_cipher_suites;
9214 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9215
9216 /*signal strength in mBm (100*dBm) */
9217 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9218
9219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309220 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009221#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009222
Sunil Duttc69bccb2014-05-26 21:30:20 +05309223 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9224 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009225 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9226 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9227
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309228 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9229
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309230 EXIT();
9231 return 0;
9232}
9233
9234/* In this function we are registering wiphy. */
9235int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9236{
9237 ENTER();
9238 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 if (0 > wiphy_register(wiphy))
9240 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309241 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9243 return -EIO;
9244 }
9245
9246 EXIT();
9247 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309248}
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309250/* In this function we are updating channel list when,
9251 regulatory domain is FCC and country code is US.
9252 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9253 As per FCC smart phone is not a indoor device.
9254 GO should not opeate on indoor channels */
9255void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9256{
9257 int j;
9258 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9259 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9260 //Default counrtycode from NV at the time of wiphy initialization.
9261 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9262 &defaultCountryCode[0]))
9263 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009264 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309265 }
9266 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9267 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309268 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309269 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309270 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309271 return;
9272 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309273 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309274 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309275 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309276 // Mark UNII -1 band channel as passive
9277 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9278 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9279 }
9280 }
9281}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309282/* This function registers for all frame which supplicant is interested in */
9283void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009284{
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9286 /* Register for all P2P action, public action etc frames */
9287 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009288 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309289 /* Register frame indication call back */
9290 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 /* Right now we are registering these frame when driver is getting
9292 initialized. Once we will move to 2.6.37 kernel, in which we have
9293 frame register ops, we will move this code as a part of that */
9294 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9297
9298 /* GAS Initial Response */
9299 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9300 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309301
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 /* GAS Comeback Request */
9303 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9304 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9305
9306 /* GAS Comeback Response */
9307 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9308 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9309
9310 /* P2P Public Action */
9311 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309312 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 P2P_PUBLIC_ACTION_FRAME_SIZE );
9314
9315 /* P2P Action */
9316 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9317 (v_U8_t*)P2P_ACTION_FRAME,
9318 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009319
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309320 /* WNM BSS Transition Request frame */
9321 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9322 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9323 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009324
9325 /* WNM-Notification */
9326 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9327 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9328 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009329}
9330
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309331void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009332{
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9334 /* Register for all P2P action, public action etc frames */
9335 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9336
Jeff Johnsone7245742012-09-05 17:12:55 -07009337 ENTER();
9338
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 /* Right now we are registering these frame when driver is getting
9340 initialized. Once we will move to 2.6.37 kernel, in which we have
9341 frame register ops, we will move this code as a part of that */
9342 /* GAS Initial Request */
9343
9344 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9345 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9346
9347 /* GAS Initial Response */
9348 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9349 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 /* GAS Comeback Request */
9352 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9353 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9354
9355 /* GAS Comeback Response */
9356 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9357 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9358
9359 /* P2P Public Action */
9360 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309361 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 P2P_PUBLIC_ACTION_FRAME_SIZE );
9363
9364 /* P2P Action */
9365 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9366 (v_U8_t*)P2P_ACTION_FRAME,
9367 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009368 /* WNM-Notification */
9369 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9370 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9371 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009372}
9373
9374#ifdef FEATURE_WLAN_WAPI
9375void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309376 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009377{
9378 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9379 tCsrRoamSetKey setKey;
9380 v_BOOL_t isConnected = TRUE;
9381 int status = 0;
9382 v_U32_t roamId= 0xFF;
9383 tANI_U8 *pKeyPtr = NULL;
9384 int n = 0;
9385
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9387 __func__, hdd_device_modetoString(pAdapter->device_mode),
9388 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009389
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309390 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 setKey.keyId = key_index; // Store Key ID
9392 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9393 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9394 setKey.paeRole = 0 ; // the PAE role
9395 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9396 {
9397 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9398 }
9399 else
9400 {
9401 isConnected = hdd_connIsConnected(pHddStaCtx);
9402 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9403 }
9404 setKey.keyLength = key_Len;
9405 pKeyPtr = setKey.Key;
9406 memcpy( pKeyPtr, key, key_Len);
9407
Arif Hussain6d2a3322013-11-17 19:50:10 -08009408 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 __func__, key_Len);
9410 for (n = 0 ; n < key_Len; n++)
9411 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9412 __func__,n,setKey.Key[n]);
9413
9414 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9415 if ( isConnected )
9416 {
9417 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9418 pAdapter->sessionId, &setKey, &roamId );
9419 }
9420 if ( status != 0 )
9421 {
9422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9423 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9424 __LINE__, status );
9425 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9426 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309427 /* Need to clear any trace of key value in the memory.
9428 * Thus zero out the memory even though it is local
9429 * variable.
9430 */
9431 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009432}
9433#endif /* FEATURE_WLAN_WAPI*/
9434
9435#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309436int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 beacon_data_t **ppBeacon,
9438 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009439#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309440int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009441 beacon_data_t **ppBeacon,
9442 struct cfg80211_beacon_data *params,
9443 int dtim_period)
9444#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309445{
Jeff Johnson295189b2012-06-20 16:38:30 -07009446 int size;
9447 beacon_data_t *beacon = NULL;
9448 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309449 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9450 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009451
Jeff Johnsone7245742012-09-05 17:12:55 -07009452 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309454 {
9455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9456 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
9460 old = pAdapter->sessionCtx.ap.beacon;
9461
9462 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9465 FL("session(%d) old and new heads points to NULL"),
9466 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309468 }
9469
9470 if (params->tail && !params->tail_len)
9471 {
9472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9473 FL("tail_len is zero but tail is not NULL"));
9474 return -EINVAL;
9475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009476
Jeff Johnson295189b2012-06-20 16:38:30 -07009477#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9478 /* Kernel 3.0 is not updating dtim_period for set beacon */
9479 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309480 {
9481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9482 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309484 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009485#endif
9486
Kapil Gupta137ef892016-12-13 19:38:00 +05309487 if (params->head)
9488 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 head = params->head;
9491 } else
9492 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309494 head = old->head;
9495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009496
Kapil Gupta137ef892016-12-13 19:38:00 +05309497 if (params->tail || !old)
9498 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309500 tail = params->tail;
9501 } else
9502 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309504 tail = old->tail;
9505 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009506
Kapil Gupta137ef892016-12-13 19:38:00 +05309507 if (params->proberesp_ies || !old)
9508 {
9509 proberesp_ies_len = params->proberesp_ies_len;
9510 proberesp_ies = params->proberesp_ies;
9511 } else
9512 {
9513 proberesp_ies_len = old->proberesp_ies_len;
9514 proberesp_ies = old->proberesp_ies;
9515 }
9516
9517 if (params->assocresp_ies || !old)
9518 {
9519 assocresp_ies_len = params->assocresp_ies_len;
9520 assocresp_ies = params->assocresp_ies;
9521 } else
9522 {
9523 assocresp_ies_len = old->assocresp_ies_len;
9524 assocresp_ies = old->assocresp_ies;
9525 }
9526
9527 size = sizeof(beacon_data_t) + head_len + tail_len +
9528 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529
9530 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309532 {
9533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9534 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009537
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009538#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309539 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 beacon->dtim_period = params->dtim_period;
9541 else
9542 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009543#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309544 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009545 beacon->dtim_period = dtim_period;
9546 else
9547 beacon->dtim_period = old->dtim_period;
9548#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309549
Jeff Johnson295189b2012-06-20 16:38:30 -07009550 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9551 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309552 beacon->proberesp_ies = beacon->tail + tail_len;
9553 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9554
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 beacon->head_len = head_len;
9556 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309557 beacon->proberesp_ies_len = proberesp_ies_len;
9558 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009559
c_manjee527ecac2017-01-25 12:25:27 +05309560 if (head && head_len)
9561 memcpy(beacon->head, head, head_len);
9562 if (tail && tail_len)
9563 memcpy(beacon->tail, tail, tail_len);
9564 if (proberesp_ies && proberesp_ies_len)
9565 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9566 if (assocresp_ies && assocresp_ies_len)
9567 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009568
9569 *ppBeacon = beacon;
9570
9571 kfree(old);
9572
9573 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009574}
Jeff Johnson295189b2012-06-20 16:38:30 -07009575
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309576v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9577#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9578 const v_U8_t *pIes,
9579#else
9580 v_U8_t *pIes,
9581#endif
9582 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009583{
9584 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309585 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309589 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 elem_id = ptr[0];
9591 elem_len = ptr[1];
9592 left -= 2;
9593 if(elem_len > left)
9594 {
9595 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009596 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 eid,elem_len,left);
9598 return NULL;
9599 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309600 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 {
9602 return ptr;
9603 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309604
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 left -= elem_len;
9606 ptr += (elem_len + 2);
9607 }
9608 return NULL;
9609}
9610
Jeff Johnson295189b2012-06-20 16:38:30 -07009611/* Check if rate is 11g rate or not */
9612static int wlan_hdd_rate_is_11g(u8 rate)
9613{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009614 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 u8 i;
9616 for (i = 0; i < 8; i++)
9617 {
9618 if(rate == gRateArray[i])
9619 return TRUE;
9620 }
9621 return FALSE;
9622}
9623
9624/* Check for 11g rate and set proper 11g only mode */
9625static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9626 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9627{
9628 u8 i, num_rates = pIe[0];
9629
9630 pIe += 1;
9631 for ( i = 0; i < num_rates; i++)
9632 {
9633 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9634 {
9635 /* If rate set have 11g rate than change the mode to 11G */
9636 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9637 if (pIe[i] & BASIC_RATE_MASK)
9638 {
9639 /* If we have 11g rate as basic rate, it means mode
9640 is 11g only mode.
9641 */
9642 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9643 *pCheckRatesfor11g = FALSE;
9644 }
9645 }
9646 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9647 {
9648 *require_ht = TRUE;
9649 }
9650 }
9651 return;
9652}
9653
9654static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9655{
9656 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9657 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9658 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9659 u8 checkRatesfor11g = TRUE;
9660 u8 require_ht = FALSE;
9661 u8 *pIe=NULL;
9662
9663 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9664
9665 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9666 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9667 if (pIe != NULL)
9668 {
9669 pIe += 1;
9670 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9671 &pConfig->SapHw_mode);
9672 }
9673
9674 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9675 WLAN_EID_EXT_SUPP_RATES);
9676 if (pIe != NULL)
9677 {
9678
9679 pIe += 1;
9680 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9681 &pConfig->SapHw_mode);
9682 }
9683
9684 if( pConfig->channel > 14 )
9685 {
9686 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9687 }
9688
9689 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9690 WLAN_EID_HT_CAPABILITY);
9691
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309692 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 {
9694 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9695 if(require_ht)
9696 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9697 }
9698}
9699
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309700static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9701 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9702{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009703 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309704 v_U8_t *pIe = NULL;
9705 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9706
9707 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9708 pBeacon->tail, pBeacon->tail_len);
9709
9710 if (pIe)
9711 {
9712 ielen = pIe[1] + 2;
9713 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9714 {
9715 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9716 }
9717 else
9718 {
9719 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9720 return -EINVAL;
9721 }
9722 *total_ielen += ielen;
9723 }
9724 return 0;
9725}
9726
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009727static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9728 v_U8_t *genie, v_U8_t *total_ielen)
9729{
9730 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9731 int left = pBeacon->tail_len;
9732 v_U8_t *ptr = pBeacon->tail;
9733 v_U8_t elem_id, elem_len;
9734 v_U16_t ielen = 0;
9735
9736 if ( NULL == ptr || 0 == left )
9737 return;
9738
9739 while (left >= 2)
9740 {
9741 elem_id = ptr[0];
9742 elem_len = ptr[1];
9743 left -= 2;
9744 if (elem_len > left)
9745 {
9746 hddLog( VOS_TRACE_LEVEL_ERROR,
9747 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9748 elem_id, elem_len, left);
9749 return;
9750 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309751 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009752 {
9753 /* skipping the VSIE's which we don't want to include or
9754 * it will be included by existing code
9755 */
9756 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9757#ifdef WLAN_FEATURE_WFD
9758 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9759#endif
9760 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9761 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9762 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9763 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9764 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9765 {
9766 ielen = ptr[1] + 2;
9767 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9768 {
9769 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9770 *total_ielen += ielen;
9771 }
9772 else
9773 {
9774 hddLog( VOS_TRACE_LEVEL_ERROR,
9775 "IE Length is too big "
9776 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9777 elem_id, elem_len, *total_ielen);
9778 }
9779 }
9780 }
9781
9782 left -= elem_len;
9783 ptr += (elem_len + 2);
9784 }
9785 return;
9786}
9787
Kapil Gupta137ef892016-12-13 19:38:00 +05309788int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009789{
9790 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309791 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009793 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309794 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009795
9796 genie = vos_mem_malloc(MAX_GENIE_LEN);
9797
9798 if(genie == NULL) {
9799
9800 return -ENOMEM;
9801 }
9802
Kapil Gupta137ef892016-12-13 19:38:00 +05309803 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309804 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9805 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309807 hddLog(LOGE,
9808 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309809 ret = -EINVAL;
9810 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 }
9812
9813#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309814 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9815 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9816 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309817 hddLog(LOGE,
9818 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309819 ret = -EINVAL;
9820 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 }
9822#endif
9823
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309824 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9825 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309827 hddLog(LOGE,
9828 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309829 ret = -EINVAL;
9830 goto done;
9831 }
9832
9833 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9834 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009835 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009837
9838 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9839 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9840 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9841 {
9842 hddLog(LOGE,
9843 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009844 ret = -EINVAL;
9845 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009846 }
9847
9848 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9849 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9850 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9851 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9852 ==eHAL_STATUS_FAILURE)
9853 {
9854 hddLog(LOGE,
9855 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009856 ret = -EINVAL;
9857 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 }
9859
9860 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309861 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309863 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 u8 probe_rsp_ie_len[3] = {0};
9865 u8 counter = 0;
9866 /* Check Probe Resp Length if it is greater then 255 then Store
9867 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9868 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9869 Store More then 255 bytes into One Variable.
9870 */
9871 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9872 {
9873 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9874 {
9875 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9876 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9877 }
9878 else
9879 {
9880 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9881 rem_probe_resp_ie_len = 0;
9882 }
9883 }
9884
9885 rem_probe_resp_ie_len = 0;
9886
9887 if (probe_rsp_ie_len[0] > 0)
9888 {
9889 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9890 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309891 (tANI_U8*)&pBeacon->
9892 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 probe_rsp_ie_len[0], NULL,
9894 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9895 {
9896 hddLog(LOGE,
9897 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009898 ret = -EINVAL;
9899 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 }
9901 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9902 }
9903
9904 if (probe_rsp_ie_len[1] > 0)
9905 {
9906 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9907 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309908 (tANI_U8*)&pBeacon->
9909 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 probe_rsp_ie_len[1], NULL,
9911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9912 {
9913 hddLog(LOGE,
9914 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009915 ret = -EINVAL;
9916 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
9918 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9919 }
9920
9921 if (probe_rsp_ie_len[2] > 0)
9922 {
9923 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9924 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309925 (tANI_U8*)&pBeacon->
9926 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 probe_rsp_ie_len[2], NULL,
9928 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9929 {
9930 hddLog(LOGE,
9931 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009932 ret = -EINVAL;
9933 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 }
9935 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9936 }
9937
9938 if (probe_rsp_ie_len[1] == 0 )
9939 {
9940 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9941 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9942 eANI_BOOLEAN_FALSE) )
9943 {
9944 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009945 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 }
9947 }
9948
9949 if (probe_rsp_ie_len[2] == 0 )
9950 {
9951 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9952 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9953 eANI_BOOLEAN_FALSE) )
9954 {
9955 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009956 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 }
9958 }
9959
9960 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9961 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9962 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9963 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9964 == eHAL_STATUS_FAILURE)
9965 {
9966 hddLog(LOGE,
9967 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009968 ret = -EINVAL;
9969 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 }
9971 }
9972 else
9973 {
9974 // Reset WNI_CFG_PROBE_RSP Flags
9975 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9976
9977 hddLog(VOS_TRACE_LEVEL_INFO,
9978 "%s: No Probe Response IE received in set beacon",
9979 __func__);
9980 }
9981
9982 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309983 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009984 {
9985 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309986 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9987 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9989 {
9990 hddLog(LOGE,
9991 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009992 ret = -EINVAL;
9993 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009994 }
9995
9996 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9997 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9998 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9999 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10000 == eHAL_STATUS_FAILURE)
10001 {
10002 hddLog(LOGE,
10003 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010004 ret = -EINVAL;
10005 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 }
10007 }
10008 else
10009 {
10010 hddLog(VOS_TRACE_LEVEL_INFO,
10011 "%s: No Assoc Response IE received in set beacon",
10012 __func__);
10013
10014 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10015 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10016 eANI_BOOLEAN_FALSE) )
10017 {
10018 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010019 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 }
10021 }
10022
Jeff Johnsone7245742012-09-05 17:12:55 -070010023done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010025 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010026}
Jeff Johnson295189b2012-06-20 16:38:30 -070010027
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010028/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 * FUNCTION: wlan_hdd_validate_operation_channel
10030 * called by wlan_hdd_cfg80211_start_bss() and
10031 * wlan_hdd_cfg80211_set_channel()
10032 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010033 * channel list.
10034 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010035VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010036{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 v_U32_t num_ch = 0;
10039 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10040 u32 indx = 0;
10041 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010042 v_U8_t fValidChannel = FALSE, count = 0;
10043 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010044
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10046
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010047 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010049 /* Validate the channel */
10050 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010052 if ( channel == rfChannels[count].channelNum )
10053 {
10054 fValidChannel = TRUE;
10055 break;
10056 }
10057 }
10058 if (fValidChannel != TRUE)
10059 {
10060 hddLog(VOS_TRACE_LEVEL_ERROR,
10061 "%s: Invalid Channel [%d]", __func__, channel);
10062 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 }
10064 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010065 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010067 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10068 valid_ch, &num_ch))
10069 {
10070 hddLog(VOS_TRACE_LEVEL_ERROR,
10071 "%s: failed to get valid channel list", __func__);
10072 return VOS_STATUS_E_FAILURE;
10073 }
10074 for (indx = 0; indx < num_ch; indx++)
10075 {
10076 if (channel == valid_ch[indx])
10077 {
10078 break;
10079 }
10080 }
10081
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010082 if (indx >= num_ch)
10083 {
10084 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10085 {
10086 eCsrBand band;
10087 unsigned int freq;
10088
10089 sme_GetFreqBand(hHal, &band);
10090
10091 if (eCSR_BAND_5G == band)
10092 {
10093#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10094 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10095 {
10096 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010097 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010098 }
10099 else
10100 {
10101 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010102 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010103 }
10104#else
10105 freq = ieee80211_channel_to_frequency(channel);
10106#endif
10107 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10108 return VOS_STATUS_SUCCESS;
10109 }
10110 }
10111
10112 hddLog(VOS_TRACE_LEVEL_ERROR,
10113 "%s: Invalid Channel [%d]", __func__, channel);
10114 return VOS_STATUS_E_FAILURE;
10115 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010117
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119
Jeff Johnson295189b2012-06-20 16:38:30 -070010120}
10121
Viral Modi3a32cc52013-02-08 11:14:52 -080010122/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010123 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010124 * This function is used to set the channel number
10125 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010126static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010127 struct ieee80211_channel *chan,
10128 enum nl80211_channel_type channel_type
10129 )
10130{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010131 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010132 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010133 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010134 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010135 hdd_context_t *pHddCtx;
10136 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010137
10138 ENTER();
10139
10140 if( NULL == dev )
10141 {
10142 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010143 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010144 return -ENODEV;
10145 }
10146 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10149 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10150 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010151 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010152 "%s: device_mode = %s (%d) freq = %d", __func__,
10153 hdd_device_modetoString(pAdapter->device_mode),
10154 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010155
10156 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10157 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010158 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010159 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010160 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010161 }
10162
10163 /*
10164 * Do freq to chan conversion
10165 * TODO: for 11a
10166 */
10167
10168 channel = ieee80211_frequency_to_channel(freq);
10169
10170 /* Check freq range */
10171 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10172 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10173 {
10174 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010175 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010176 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10177 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10178 return -EINVAL;
10179 }
10180
10181 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10182
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010183 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10184 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010185 {
10186 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10187 {
10188 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010189 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010190 return -EINVAL;
10191 }
10192 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10193 "%s: set channel to [%d] for device mode =%d",
10194 __func__, channel,pAdapter->device_mode);
10195 }
10196 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010197 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010198 )
10199 {
10200 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10201 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10202 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10203
10204 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10205 {
10206 /* Link is up then return cant set channel*/
10207 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010208 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010209 return -EINVAL;
10210 }
10211
10212 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10213 pHddStaCtx->conn_info.operationChannel = channel;
10214 pRoamProfile->ChannelInfo.ChannelList =
10215 &pHddStaCtx->conn_info.operationChannel;
10216 }
10217 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010219 )
10220 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010221 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10222 {
10223 if(VOS_STATUS_SUCCESS !=
10224 wlan_hdd_validate_operation_channel(pAdapter,channel))
10225 {
10226 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010227 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010228 return -EINVAL;
10229 }
10230 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10231 }
10232 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010233 {
10234 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10235
10236 /* If auto channel selection is configured as enable/ 1 then ignore
10237 channel set by supplicant
10238 */
10239 if ( cfg_param->apAutoChannelSelection )
10240 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010241 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10242 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010243 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010244 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10245 __func__, hdd_device_modetoString(pAdapter->device_mode),
10246 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010247 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010248 else
10249 {
10250 if(VOS_STATUS_SUCCESS !=
10251 wlan_hdd_validate_operation_channel(pAdapter,channel))
10252 {
10253 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010254 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010255 return -EINVAL;
10256 }
10257 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10258 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010259 }
10260 }
10261 else
10262 {
10263 hddLog(VOS_TRACE_LEVEL_FATAL,
10264 "%s: Invalid device mode failed to set valid channel", __func__);
10265 return -EINVAL;
10266 }
10267 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010268 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010269}
10270
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010271static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10272 struct net_device *dev,
10273 struct ieee80211_channel *chan,
10274 enum nl80211_channel_type channel_type
10275 )
10276{
10277 int ret;
10278
10279 vos_ssr_protect(__func__);
10280 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10281 vos_ssr_unprotect(__func__);
10282
10283 return ret;
10284}
10285
Anurag Chouhan83026002016-12-13 22:46:21 +053010286#ifdef DHCP_SERVER_OFFLOAD
10287void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10288 VOS_STATUS status)
10289{
10290 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10291
10292 ENTER();
10293
10294 if (NULL == adapter)
10295 {
10296 hddLog(VOS_TRACE_LEVEL_ERROR,
10297 "%s: adapter is NULL",__func__);
10298 return;
10299 }
10300
10301 adapter->dhcp_status.dhcp_offload_status = status;
10302 vos_event_set(&adapter->dhcp_status.vos_event);
10303 return;
10304}
10305
10306/**
10307 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10308 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010309 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010310 *
10311 * Return: None
10312 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010313VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10314 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010315{
10316 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10317 sir_dhcp_srv_offload_info dhcp_srv_info;
10318 tANI_U8 num_entries = 0;
10319 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10320 tANI_U8 num;
10321 tANI_U32 temp;
10322 VOS_STATUS ret;
10323
10324 ENTER();
10325
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010326 if (!re_init) {
10327 ret = wlan_hdd_validate_context(hdd_ctx);
10328 if (0 != ret)
10329 return VOS_STATUS_E_INVAL;
10330 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010331
10332 /* Prepare the request to send to SME */
10333 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10334 if (NULL == dhcp_srv_info) {
10335 hddLog(VOS_TRACE_LEVEL_ERROR,
10336 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10337 return VOS_STATUS_E_NOMEM;
10338 }
10339
10340 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10341
10342 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10343 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10344 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10345 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10346 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10347 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10348
10349 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10350 srv_ip,
10351 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010352 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010353 if (num_entries != IPADDR_NUM_ENTRIES) {
10354 hddLog(VOS_TRACE_LEVEL_ERROR,
10355 "%s: incorrect IP address (%s) assigned for DHCP server!",
10356 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10357 vos_mem_free(dhcp_srv_info);
10358 return VOS_STATUS_E_FAILURE;
10359 }
10360
10361 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10362 hddLog(VOS_TRACE_LEVEL_ERROR,
10363 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10364 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10365 vos_mem_free(dhcp_srv_info);
10366 return VOS_STATUS_E_FAILURE;
10367 }
10368
10369 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10370 hddLog(VOS_TRACE_LEVEL_ERROR,
10371 "%s: invalid IP address (%s)! The last field must be less than 100!",
10372 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10373 vos_mem_free(dhcp_srv_info);
10374 return VOS_STATUS_E_FAILURE;
10375 }
10376
10377 for (num = 0; num < num_entries; num++) {
10378 temp = srv_ip[num];
10379 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10380 }
10381
10382 if (eHAL_STATUS_SUCCESS !=
10383 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10384 hddLog(VOS_TRACE_LEVEL_ERROR,
10385 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10386 vos_mem_free(dhcp_srv_info);
10387 return VOS_STATUS_E_FAILURE;
10388 }
10389
10390 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10391 "%s: enable DHCP Server offload successfully!", __func__);
10392
10393 vos_mem_free(dhcp_srv_info);
10394 return 0;
10395}
10396#endif /* DHCP_SERVER_OFFLOAD */
10397
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010398/*
10399 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10400 * @wiphy_chan: wiphy channel number
10401 * @rfChannel: channel hw value
10402 * @disable: Disable/enable the flags
10403 *
10404 * Modify wiphy flags and cds state if channel is indoor.
10405 *
10406 * Return: void
10407 */
10408void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10409 v_U32_t rfChannel, bool disable)
10410{
10411 v_U32_t channelLoop;
10412 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10413
10414 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10415
10416 if (rfChannels[channelLoop].channelNum == rfChannel) {
10417 channelEnum = (eRfChannels)channelLoop;
10418 break;
10419 }
10420 }
10421
10422 if (INVALID_RF_CHANNEL == channelEnum)
10423 return;
10424
10425 if (disable) {
10426 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10427 wiphy_chan->flags |=
10428 IEEE80211_CHAN_DISABLED;
10429 regChannels[channelEnum].enabled =
10430 NV_CHANNEL_DISABLE;
10431 }
10432 } else {
10433 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10434 wiphy_chan->flags &=
10435 ~IEEE80211_CHAN_DISABLED;
10436 /*
10437 * Indoor channels are marked as DFS
10438 * during regulatory processing
10439 */
10440
10441 regChannels[channelEnum].enabled =
10442 NV_CHANNEL_DFS;
10443 }
10444 }
10445
10446}
10447
10448void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10449 bool disable)
10450{
10451 int band_num;
10452 int chan_num;
10453 v_U32_t rfChannel;
10454 struct ieee80211_channel *wiphy_chan;
10455 struct wiphy *wiphy;
10456
10457 ENTER();
10458 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10459
10460 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010461 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010462
10463 if (wiphy->bands[band_num] == NULL)
10464 continue;
10465
10466 for (chan_num = 0;
10467 chan_num < wiphy->bands[band_num]->n_channels;
10468 chan_num++) {
10469
10470 wiphy_chan =
10471 &(wiphy->bands[band_num]->channels[chan_num]);
10472 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10473
10474 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10475 disable);
10476 }
10477 }
10478 EXIT();
10479}
10480
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010481/*
10482 * FUNCTION: wlan_hdd_disconnect
10483 * This function is used to issue a disconnect request to SME
10484 */
10485int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10486{
10487 int status, result = 0;
10488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10489 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10490 long ret;
10491 eConnectionState prev_conn_state;
10492 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10493
10494 ENTER();
10495
10496 status = wlan_hdd_validate_context(pHddCtx);
10497 if (0 != status)
10498 {
10499 return status;
10500 }
10501 /* Indicate sme of disconnect so that in progress connection or preauth
10502 * can be aborted
10503 */
10504 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10505 pAdapter->sessionId);
10506 pHddCtx->isAmpAllowed = VOS_TRUE;
10507
10508 /* Need to apply spin lock before decreasing active sessions
10509 * as there can be chance for double decrement if context switch
10510 * Calls hdd_DisConnectHandler.
10511 */
10512
10513 prev_conn_state = pHddStaCtx->conn_info.connState;
10514
10515 spin_lock_bh(&pAdapter->lock_for_active_session);
10516 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10517 {
10518 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10519 }
10520 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10521 spin_unlock_bh(&pAdapter->lock_for_active_session);
10522 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10523
10524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10525 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10526
10527 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10528
10529 /*
10530 * stop tx queues before deleting STA/BSS context from the firmware.
10531 * tx has to be disabled because the firmware can get busy dropping
10532 * the tx frames after BSS/STA has been deleted and will not send
10533 * back a response resulting in WDI timeout
10534 */
10535 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10536 netif_tx_disable(pAdapter->dev);
10537 netif_carrier_off(pAdapter->dev);
10538
10539 wlan_hdd_check_and_stop_mon(pAdapter, true);
10540
10541 /*issue disconnect*/
10542 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10543 pAdapter->sessionId, reason);
10544 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10545 prev_conn_state != eConnectionState_Connecting)
10546 {
10547 hddLog(LOG1,
10548 FL("status = %d, already disconnected"), status);
10549 result = 0;
10550 /*
10551 * Wait here instead of returning directly. This will block the
10552 * next connect command and allow processing of the disconnect
10553 * in SME else we might hit some race conditions leading to SME
10554 * and HDD out of sync. As disconnect is already in progress,
10555 * wait here for 1 sec instead of 5 sec.
10556 */
10557 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10558 goto wait_for_disconnect;
10559 }
10560 /*
10561 * Wait here instead of returning directly, this will block the next
10562 * connect command and allow processing of the scan for ssid and
10563 * the previous connect command in CSR. Else we might hit some
10564 * race conditions leading to SME and HDD out of sync.
10565 */
10566 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10567 {
10568 hddLog(LOG1,
10569 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10570 }
10571 else if ( 0 != status )
10572 {
10573 hddLog(LOGE,
10574 FL("csrRoamDisconnect failure, returned %d"),
10575 (int)status);
10576 result = -EINVAL;
10577 goto disconnected;
10578 }
10579wait_for_disconnect:
10580 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10581 msecs_to_jiffies(wait_time));
10582 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10583 {
10584 hddLog(LOGE,
10585 "%s: Failed to disconnect, timed out", __func__);
10586 result = -ETIMEDOUT;
10587 }
10588disconnected:
10589 hddLog(LOG1,
10590 FL("Set HDD connState to eConnectionState_NotConnected"));
10591 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10592#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10593 /* Sending disconnect event to userspace for kernel version < 3.11
10594 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10595 */
10596 hddLog(LOG1, FL("Send disconnected event to userspace"));
10597
10598 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10599 WLAN_REASON_UNSPECIFIED);
10600#endif
10601
10602 EXIT();
10603 return result;
10604}
10605
10606/*
10607 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10608 * on indoor channel
10609 * @hdd_ctx: pointer to hdd context
10610 *
10611 * STA should be disconnected before starting the SAP if it is on indoor
10612 * channel.
10613 *
10614 * Return: void
10615 */
10616void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10617{
10618
10619 hdd_adapter_t *sta_adapter;
10620 tANI_U8 sta_chan;
10621
10622 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10623
10624 if (!sta_chan) {
10625 hddLog(LOG1, FL("STA not connected"));
10626 return;
10627 }
10628
10629 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10630
10631 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10632 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10633 sta_chan);
10634 return;
10635 }
10636
10637 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10638
10639 if (!sta_adapter) {
10640 hddLog(LOG1, FL("STA adapter doesn't exist"));
10641 return;
10642 }
10643
10644 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10645 /* Issue Disconnect request */
10646 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10647}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010648
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010649int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10650{
10651 struct hdd_cache_channels *cache_chann;
10652 struct wiphy *wiphy;
10653 int freq, status, rfChannel;
10654 int i, band_num, channel_num;
10655 struct ieee80211_channel *wiphy_channel;
10656
10657 ENTER();
10658
10659 if (!hdd_ctx) {
10660 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10661 return -EINVAL;
10662 }
10663
10664 wiphy = hdd_ctx->wiphy;
10665
10666 mutex_lock(&hdd_ctx->cache_channel_lock);
10667
10668 cache_chann = hdd_ctx->orginal_channels;
10669
10670 if (!cache_chann || !cache_chann->num_channels) {
10671 hddLog(VOS_TRACE_LEVEL_INFO,
10672 "%s channel list is NULL or num channels are zero",
10673 __func__);
10674 mutex_unlock(&hdd_ctx->cache_channel_lock);
10675 return -EINVAL;
10676 }
10677
10678 for (i = 0; i < cache_chann->num_channels; i++) {
10679 status = hdd_wlan_get_freq(
10680 cache_chann->channel_info[i].channel_num,
10681 &freq);
10682
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010683 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10684 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010685 for (channel_num = 0; channel_num <
10686 wiphy->bands[band_num]->n_channels;
10687 channel_num++) {
10688 wiphy_channel = &(wiphy->bands[band_num]->
10689 channels[channel_num]);
10690 if (wiphy_channel->center_freq == freq) {
10691 rfChannel = wiphy_channel->hw_value;
10692 /*
10693 *Restore the orginal states
10694 *of the channels
10695 */
10696 vos_nv_set_channel_state(
10697 rfChannel,
10698 cache_chann->
10699 channel_info[i].reg_status);
10700 wiphy_channel->flags =
10701 cache_chann->
10702 channel_info[i].wiphy_status;
10703 break;
10704 }
10705 }
10706 if (channel_num < wiphy->bands[band_num]->n_channels)
10707 break;
10708 }
10709 }
10710
10711 mutex_unlock(&hdd_ctx->cache_channel_lock);
10712
10713 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10714 if (status)
10715 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10716 EXIT();
10717
10718 return 0;
10719}
10720
10721/*
10722 * wlan_hdd_disable_channels() - Cache the the channels
10723 * and current state of the channels from the channel list
10724 * received in the command and disable the channels on the
10725 * wiphy and NV table.
10726 * @hdd_ctx: Pointer to hdd context
10727 *
10728 * @return: 0 on success, Error code on failure
10729 */
10730
10731static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10732{
10733 struct hdd_cache_channels *cache_chann;
10734 struct wiphy *wiphy;
10735 int freq, status, rfChannel;
10736 int i, band_num, band_ch_num;
10737 struct ieee80211_channel *wiphy_channel;
10738
10739 if (!hdd_ctx) {
10740 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10741 return -EINVAL;
10742 }
10743
10744 wiphy = hdd_ctx->wiphy;
10745
10746 mutex_lock(&hdd_ctx->cache_channel_lock);
10747 cache_chann = hdd_ctx->orginal_channels;
10748
10749 if (!cache_chann || !cache_chann->num_channels) {
10750 hddLog(VOS_TRACE_LEVEL_INFO,
10751 "%s channel list is NULL or num channels are zero",
10752 __func__);
10753 mutex_unlock(&hdd_ctx->cache_channel_lock);
10754 return -EINVAL;
10755 }
10756
10757 for (i = 0; i < cache_chann->num_channels; i++) {
10758 status = hdd_wlan_get_freq(
10759 cache_chann->channel_info[i].channel_num,
10760 &freq);
10761
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010762 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010763 band_num++) {
10764 for (band_ch_num = 0; band_ch_num <
10765 wiphy->bands[band_num]->n_channels;
10766 band_ch_num++) {
10767 wiphy_channel = &(wiphy->bands[band_num]->
10768 channels[band_ch_num]);
10769 if (wiphy_channel->center_freq == freq) {
10770 rfChannel = wiphy_channel->hw_value;
10771 /*
10772 * Cache the current states of
10773 * the channels
10774 */
10775 cache_chann->
10776 channel_info[i].reg_status =
10777 vos_nv_getChannelEnabledState(
10778 rfChannel);
10779
10780 cache_chann->
10781 channel_info[i].wiphy_status =
10782 wiphy_channel->flags;
10783 hddLog(VOS_TRACE_LEVEL_INFO,
10784 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10785 cache_chann->
10786 channel_info[i].channel_num,
10787 cache_chann->
10788 channel_info[i].reg_status,
10789 wiphy_channel->flags);
10790
10791 vos_nv_set_channel_state(
10792 rfChannel,
10793 NV_CHANNEL_DISABLE);
10794 wiphy_channel->flags |=
10795 IEEE80211_CHAN_DISABLED;
10796 break;
10797 }
10798 }
10799 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10800 break;
10801 }
10802 }
10803
10804 mutex_unlock(&hdd_ctx->cache_channel_lock);
10805 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10806 return 0;
10807}
10808
Jeff Johnson295189b2012-06-20 16:38:30 -070010809#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10810static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10811 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010812#else
10813static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10814 struct cfg80211_beacon_data *params,
10815 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010816 enum nl80211_hidden_ssid hidden_ssid,
10817 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010819{
10820 tsap_Config_t *pConfig;
10821 beacon_data_t *pBeacon = NULL;
10822 struct ieee80211_mgmt *pMgmt_frame;
10823 v_U8_t *pIe=NULL;
10824 v_U16_t capab_info;
10825 eCsrAuthType RSNAuthType;
10826 eCsrEncryptionType RSNEncryptType;
10827 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010828 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010829 tpWLAN_SAPEventCB pSapEventCallback;
10830 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010831 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010832 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010834 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010836 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010837 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010838 v_BOOL_t MFPCapable = VOS_FALSE;
10839 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010840 v_BOOL_t sapEnable11AC =
10841 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010842 u_int16_t prev_rsn_length = 0;
10843
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 ENTER();
10845
Nitesh Shah9b066282017-06-06 18:05:52 +053010846 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010847 iniConfig = pHddCtx->cfg_ini;
10848
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010849 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053010850 if (iniConfig->disable_indoor_channel &&
10851 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010852 hdd_update_indoor_channel(pHddCtx, true);
10853
10854 if (!VOS_IS_STATUS_SUCCESS(
10855 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10856 hdd_update_indoor_channel(pHddCtx, false);
10857 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10858 FL("Can't start BSS: update channel list failed"));
10859 return eHAL_STATUS_FAILURE;
10860 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010861
10862 /* check if STA is on indoor channel */
10863 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10864 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010865 }
10866
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010867 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
10868 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
10869 wlan_hdd_disable_channels(pHddCtx);
10870 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
10871 }
10872
Jeff Johnson295189b2012-06-20 16:38:30 -070010873 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10874
10875 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10876
10877 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10878
10879 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10880
10881 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10882
10883 //channel is already set in the set_channel Call back
10884 //pConfig->channel = pCommitConfig->channel;
10885
10886 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010887 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10889
10890 pConfig->dtim_period = pBeacon->dtim_period;
10891
Arif Hussain6d2a3322013-11-17 19:50:10 -080010892 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010893 pConfig->dtim_period);
10894
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010895 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010896 {
10897 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010898 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010899 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10900 {
10901 tANI_BOOLEAN restartNeeded;
10902 pConfig->ieee80211d = 1;
10903 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10904 sme_setRegInfo(hHal, pConfig->countryCode);
10905 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10906 }
10907 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010909 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010910 pConfig->ieee80211d = 1;
10911 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10912 sme_setRegInfo(hHal, pConfig->countryCode);
10913 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010915 else
10916 {
10917 pConfig->ieee80211d = 0;
10918 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010919 /*
10920 * If auto channel is configured i.e. channel is 0,
10921 * so skip channel validation.
10922 */
10923 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10924 {
10925 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10926 {
10927 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010928 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010929 ret = -EINVAL;
10930 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010931 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010932 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010933 }
10934 else
10935 {
10936 if(1 != pHddCtx->is_dynamic_channel_range_set)
10937 {
10938 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10939 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10940 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10941 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010942 pHddCtx->is_dynamic_channel_range_set = 0;
10943 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010944 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010945 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010946 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 {
10948 pConfig->ieee80211d = 0;
10949 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010950
10951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10952 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10953 pConfig->authType = eSAP_OPEN_SYSTEM;
10954 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10955 pConfig->authType = eSAP_SHARED_KEY;
10956 else
10957 pConfig->authType = eSAP_AUTO_SWITCH;
10958#else
10959 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10960 pConfig->authType = eSAP_OPEN_SYSTEM;
10961 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10962 pConfig->authType = eSAP_SHARED_KEY;
10963 else
10964 pConfig->authType = eSAP_AUTO_SWITCH;
10965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010966
10967 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010968
10969 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010971#ifdef SAP_AUTH_OFFLOAD
10972 /* In case of sap offload, hostapd.conf is configuted with open mode and
10973 * security is configured from ini file. Due to open mode in hostapd.conf
10974 * privacy bit is set to false which will result in not sending,
10975 * data packets as encrypted.
10976 * If enable_sap_auth_offload is enabled in ini and
10977 * sap_auth_offload_sec_type is type of WPA2-PSK,
10978 * driver will set privacy bit to 1.
10979 */
10980 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10981 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10982 pConfig->privacy = VOS_TRUE;
10983#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010984
10985 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10986
10987 /*Set wps station to configured*/
10988 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10989
10990 if(pIe)
10991 {
10992 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10993 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010994 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010995 ret = -EINVAL;
10996 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010997 }
10998 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10999 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011000 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011001 /* Check 15 bit of WPS IE as it contain information for wps state
11002 * WPS state
11003 */
11004 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11005 {
11006 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11007 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11008 {
11009 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11010 }
11011 }
11012 }
11013 else
11014 {
11015 pConfig->wps_state = SAP_WPS_DISABLED;
11016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011018
c_hpothufe599e92014-06-16 11:38:55 +053011019 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11020 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11021 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11022 eCSR_ENCRYPT_TYPE_NONE;
11023
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011025 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011026 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 WLAN_EID_RSN);
11028 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011029 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011030 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011031 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11032 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11033 pConfig->RSNWPAReqIELength);
11034 else
11035 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11036 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011037 /* The actual processing may eventually be more extensive than
11038 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 * by the app.
11040 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011041 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011042 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11043 &RSNEncryptType,
11044 &mcRSNEncryptType,
11045 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011046 &MFPCapable,
11047 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011048 pConfig->RSNWPAReqIE[1]+2,
11049 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011050
11051 if( VOS_STATUS_SUCCESS == status )
11052 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011053 /* Now copy over all the security attributes you have
11054 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011055 * */
11056 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11057 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11058 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11059 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011060 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011061 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11063 }
11064 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011065
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11067 pBeacon->tail, pBeacon->tail_len);
11068
11069 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11070 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011071 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011072 {
11073 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011074 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011075 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011076 if (pConfig->RSNWPAReqIELength <=
11077 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11078 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11079 pIe[1] + 2);
11080 else
11081 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11082 pConfig->RSNWPAReqIELength);
11083
Jeff Johnson295189b2012-06-20 16:38:30 -070011084 }
11085 else
11086 {
11087 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011088 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11089 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11090 pConfig->RSNWPAReqIELength);
11091 else
11092 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11093 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011094 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11096 &RSNEncryptType,
11097 &mcRSNEncryptType,
11098 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011099 &MFPCapable,
11100 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011101 pConfig->RSNWPAReqIE[1]+2,
11102 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011103
11104 if( VOS_STATUS_SUCCESS == status )
11105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011106 /* Now copy over all the security attributes you have
11107 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 * */
11109 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11110 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11111 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11112 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011113 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011114 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11116 }
11117 }
11118 }
11119
Kapil Gupta137ef892016-12-13 19:38:00 +053011120 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011121 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011122 ret = -EINVAL;
11123 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011124 }
11125
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11127
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011128#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 if (params->ssid != NULL)
11130 {
11131 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11132 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11133 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11134 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11135 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011136#else
11137 if (ssid != NULL)
11138 {
11139 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11140 pConfig->SSIDinfo.ssid.length = ssid_len;
11141 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11142 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11143 }
11144#endif
11145
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011146 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011148
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 /* default value */
11150 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11151 pConfig->num_accept_mac = 0;
11152 pConfig->num_deny_mac = 0;
11153
11154 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11155 pBeacon->tail, pBeacon->tail_len);
11156
11157 /* pIe for black list is following form:
11158 type : 1 byte
11159 length : 1 byte
11160 OUI : 4 bytes
11161 acl type : 1 byte
11162 no of mac addr in black list: 1 byte
11163 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164 */
11165 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 {
11167 pConfig->SapMacaddr_acl = pIe[6];
11168 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011169 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011170 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011171 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11172 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11174 for (i = 0; i < pConfig->num_deny_mac; i++)
11175 {
11176 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11177 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011178 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011179 }
11180 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11181 pBeacon->tail, pBeacon->tail_len);
11182
11183 /* pIe for white list is following form:
11184 type : 1 byte
11185 length : 1 byte
11186 OUI : 4 bytes
11187 acl type : 1 byte
11188 no of mac addr in white list: 1 byte
11189 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011190 */
11191 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 {
11193 pConfig->SapMacaddr_acl = pIe[6];
11194 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011195 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011197 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11198 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11200 for (i = 0; i < pConfig->num_accept_mac; i++)
11201 {
11202 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11203 acl_entry++;
11204 }
11205 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011206
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11208
Jeff Johnsone7245742012-09-05 17:12:55 -070011209#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011210 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011211 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11212 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011213 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11214 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011215 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11216 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011217 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11218 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011219 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011220 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011221 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011222 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011223
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011224 /* If ACS disable and selected channel <= 14
11225 * OR
11226 * ACS enabled and ACS operating band is choosen as 2.4
11227 * AND
11228 * VHT in 2.4G Disabled
11229 * THEN
11230 * Fallback to 11N mode
11231 */
11232 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11233 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011234 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011235 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011236 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011237 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11238 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011239 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11240 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011241 }
11242#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011243
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 // ht_capab is not what the name conveys,this is used for protection bitmap
11245 pConfig->ht_capab =
11246 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11247
Kapil Gupta137ef892016-12-13 19:38:00 +053011248 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011249 {
11250 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011251 ret = -EINVAL;
11252 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 }
11254
11255 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011256 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11258 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011259 pConfig->obssProtEnabled =
11260 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011261
Chet Lanctot8cecea22014-02-11 19:09:36 -080011262#ifdef WLAN_FEATURE_11W
11263 pConfig->mfpCapable = MFPCapable;
11264 pConfig->mfpRequired = MFPRequired;
11265 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11266 pConfig->mfpCapable, pConfig->mfpRequired);
11267#endif
11268
Arif Hussain6d2a3322013-11-17 19:50:10 -080011269 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011271 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11272 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11273 (int)pConfig->channel);
11274 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11275 pConfig->SapHw_mode, pConfig->privacy,
11276 pConfig->authType);
11277 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11278 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11279 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11280 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011281
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011282 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 {
11284 //Bss already started. just return.
11285 //TODO Probably it should update some beacon params.
11286 hddLog( LOGE, "Bss Already started...Ignore the request");
11287 EXIT();
11288 return 0;
11289 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011290
Agarwal Ashish51325b52014-06-16 16:50:49 +053011291 if (vos_max_concurrent_connections_reached()) {
11292 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011293 ret = -EINVAL;
11294 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011295 }
11296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 pConfig->persona = pHostapdAdapter->device_mode;
11298
Peng Xu2446a892014-09-05 17:21:18 +053011299 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11300 if ( NULL != psmeConfig)
11301 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011302 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011303 sme_GetConfigParam(hHal, psmeConfig);
11304 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011305#ifdef WLAN_FEATURE_AP_HT40_24G
11306 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11307 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11308 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11309 {
11310 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11311 sme_UpdateConfig (hHal, psmeConfig);
11312 }
11313#endif
Peng Xu2446a892014-09-05 17:21:18 +053011314 vos_mem_free(psmeConfig);
11315 }
Peng Xuafc34e32014-09-25 13:23:55 +053011316 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011317
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011318 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11319
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 pSapEventCallback = hdd_hostapd_SAPEventCB;
11321 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11322 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11323 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011324 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011325 ret = -EINVAL;
11326 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 }
11328
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11331
11332 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011333
Jeff Johnson295189b2012-06-20 16:38:30 -070011334 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011335 {
11336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011337 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011338 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 VOS_ASSERT(0);
11340 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011341
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011343 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11344 VOS_STATUS_SUCCESS)
11345 {
11346 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11347 VOS_ASSERT(0);
11348 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011349 /* Initialize WMM configuation */
11350 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011351 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011352
Anurag Chouhan83026002016-12-13 22:46:21 +053011353#ifdef DHCP_SERVER_OFFLOAD
11354 /* set dhcp server offload */
11355 if (iniConfig->enable_dhcp_srv_offload &&
11356 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011357 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011358 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011359 if (!VOS_IS_STATUS_SUCCESS(status))
11360 {
11361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11362 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011363 vos_event_reset(&pHostapdState->vosEvent);
11364 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11365 status = vos_wait_single_event(&pHostapdState->vosEvent,
11366 10000);
11367 if (!VOS_IS_STATUS_SUCCESS(status)) {
11368 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011369 ret = -EINVAL;
11370 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011371 }
11372 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011373 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011374 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11375 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11376 {
11377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11378 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11379 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011380 vos_event_reset(&pHostapdState->vosEvent);
11381 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11382 status = vos_wait_single_event(&pHostapdState->vosEvent,
11383 10000);
11384 if (!VOS_IS_STATUS_SUCCESS(status)) {
11385 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011386 ret = -EINVAL;
11387 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011388 }
11389 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011390 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011391#ifdef MDNS_OFFLOAD
11392 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011393 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011394 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11395 if (VOS_IS_STATUS_SUCCESS(status))
11396 {
11397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11398 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011399 vos_event_reset(&pHostapdState->vosEvent);
11400 if (VOS_STATUS_SUCCESS ==
11401 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11402 status = vos_wait_single_event(&pHostapdState->vosEvent,
11403 10000);
11404 if (!VOS_IS_STATUS_SUCCESS(status)) {
11405 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011406 ret = -EINVAL;
11407 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011408 }
11409 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011410 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011411 status = vos_wait_single_event(&pHostapdAdapter->
11412 mdns_status.vos_event, 2000);
11413 if (!VOS_IS_STATUS_SUCCESS(status) ||
11414 pHostapdAdapter->mdns_status.mdns_enable_status ||
11415 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11416 pHostapdAdapter->mdns_status.mdns_resp_status)
11417 {
11418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11419 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11420 pHostapdAdapter->mdns_status.mdns_enable_status,
11421 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11422 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011423 vos_event_reset(&pHostapdState->vosEvent);
11424 if (VOS_STATUS_SUCCESS ==
11425 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11426 status = vos_wait_single_event(&pHostapdState->vosEvent,
11427 10000);
11428 if (!VOS_IS_STATUS_SUCCESS(status)) {
11429 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011430 ret = -EINVAL;
11431 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011432 }
11433 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011434 }
11435 }
11436#endif /* MDNS_OFFLOAD */
11437 } else {
11438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11439 ("DHCP Disabled ini %d, FW %d"),
11440 iniConfig->enable_dhcp_srv_offload,
11441 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011442 }
11443#endif /* DHCP_SERVER_OFFLOAD */
11444
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011445#ifdef WLAN_FEATURE_P2P_DEBUG
11446 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11447 {
11448 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11449 {
11450 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11451 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011452 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011453 }
11454 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11455 {
11456 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11457 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011458 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011459 }
11460 }
11461#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011462 /* Check and restart SAP if it is on Unsafe channel */
11463 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011464
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 pHostapdState->bCommit = TRUE;
11466 EXIT();
11467
11468 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011469error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011470 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11471 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011472 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011473 if (iniConfig->disable_indoor_channel &&
11474 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011475 hdd_update_indoor_channel(pHddCtx, false);
11476 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11477 }
11478
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011479 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11480 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011481}
11482
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011483#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011484static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 struct beacon_parameters *params)
11487{
11488 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011489 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011490 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011491
11492 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011493
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011494 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11495 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11496 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011497 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11498 hdd_device_modetoString(pAdapter->device_mode),
11499 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011500
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011501 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11502 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011503 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011504 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011505 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011506 }
11507
Agarwal Ashish51325b52014-06-16 16:50:49 +053011508 if (vos_max_concurrent_connections_reached()) {
11509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11510 return -EINVAL;
11511 }
11512
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011513 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011514 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 )
11516 {
11517 beacon_data_t *old,*new;
11518
11519 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011520
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011522 {
11523 hddLog(VOS_TRACE_LEVEL_WARN,
11524 FL("already beacon info added to session(%d)"),
11525 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011527 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011528
11529 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11530
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011531 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 {
11533 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011534 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 return -EINVAL;
11536 }
11537
11538 pAdapter->sessionCtx.ap.beacon = new;
11539
11540 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11541 }
11542
11543 EXIT();
11544 return status;
11545}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011546
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011547static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11548 struct net_device *dev,
11549 struct beacon_parameters *params)
11550{
11551 int ret;
11552
11553 vos_ssr_protect(__func__);
11554 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11555 vos_ssr_unprotect(__func__);
11556
11557 return ret;
11558}
11559
11560static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011561 struct net_device *dev,
11562 struct beacon_parameters *params)
11563{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011565 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11566 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011567 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011568
11569 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011570
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011571 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11572 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11573 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11574 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11575 __func__, hdd_device_modetoString(pAdapter->device_mode),
11576 pAdapter->device_mode);
11577
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011578 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11579 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011580 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011581 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011582 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011583 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011584
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011585 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011587 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 {
11589 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011590
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011592
Jeff Johnson295189b2012-06-20 16:38:30 -070011593 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011594 {
11595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11596 FL("session(%d) old and new heads points to NULL"),
11597 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011598 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011599 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011600
11601 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11602
11603 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011605 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011606 return -EINVAL;
11607 }
11608
11609 pAdapter->sessionCtx.ap.beacon = new;
11610
11611 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11612 }
11613
11614 EXIT();
11615 return status;
11616}
11617
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011618static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11619 struct net_device *dev,
11620 struct beacon_parameters *params)
11621{
11622 int ret;
11623
11624 vos_ssr_protect(__func__);
11625 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11626 vos_ssr_unprotect(__func__);
11627
11628 return ret;
11629}
11630
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011631#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11632
11633#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011634static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011636#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011637static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011638 struct net_device *dev)
11639#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011640{
11641 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011642 hdd_context_t *pHddCtx = NULL;
11643 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011644 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011645 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011646
11647 ENTER();
11648
11649 if (NULL == pAdapter)
11650 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011652 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 return -ENODEV;
11654 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011655
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011656 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11657 TRACE_CODE_HDD_CFG80211_STOP_AP,
11658 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011659 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11660 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011661 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011662 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011663 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011664 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011665
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011666 pScanInfo = &pHddCtx->scan_info;
11667
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011668 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11669 __func__, hdd_device_modetoString(pAdapter->device_mode),
11670 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011671
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011672 ret = wlan_hdd_scan_abort(pAdapter);
11673
Girish Gowli4bf7a632014-06-12 13:42:11 +053011674 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011675 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11677 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011678
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011679 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011680 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11682 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011683
Jeff Johnsone7245742012-09-05 17:12:55 -070011684 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011685 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011686 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011687 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011688 }
11689
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011690 /* Delete all associated STAs before stopping AP/P2P GO */
11691 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011692 hdd_hostapd_stop(dev);
11693
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 )
11697 {
11698 beacon_data_t *old;
11699
11700 old = pAdapter->sessionCtx.ap.beacon;
11701
11702 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011703 {
11704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11705 FL("session(%d) beacon data points to NULL"),
11706 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011709
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011711
11712 mutex_lock(&pHddCtx->sap_lock);
11713 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11714 {
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011715 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11716 hdd_wait_for_ecsa_complete(pHddCtx);
Jeff Johnson4416a782013-03-25 14:17:50 -070011717 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 {
11719 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11720
11721 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11722
11723 if (!VOS_IS_STATUS_SUCCESS(status))
11724 {
11725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011726 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011728 }
11729 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011731 /* BSS stopped, clear the active sessions for this device mode */
11732 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 }
11734 mutex_unlock(&pHddCtx->sap_lock);
11735
11736 if(status != VOS_STATUS_SUCCESS)
11737 {
11738 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011739 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 return -EINVAL;
11741 }
11742
Jeff Johnson4416a782013-03-25 14:17:50 -070011743 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11745 ==eHAL_STATUS_FAILURE)
11746 {
11747 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011748 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 }
11750
Jeff Johnson4416a782013-03-25 14:17:50 -070011751 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11753 eANI_BOOLEAN_FALSE) )
11754 {
11755 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011756 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 }
11758
11759 // Reset WNI_CFG_PROBE_RSP Flags
11760 wlan_hdd_reset_prob_rspies(pAdapter);
11761
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011762 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11763
Jeff Johnson295189b2012-06-20 16:38:30 -070011764 pAdapter->sessionCtx.ap.beacon = NULL;
11765 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011766#ifdef WLAN_FEATURE_P2P_DEBUG
11767 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11768 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11769 {
11770 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11771 "GO got removed");
11772 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11773 }
11774#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 }
11776 EXIT();
11777 return status;
11778}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011779
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011780#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11781static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11782 struct net_device *dev)
11783{
11784 int ret;
11785
11786 vos_ssr_protect(__func__);
11787 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11788 vos_ssr_unprotect(__func__);
11789
11790 return ret;
11791}
11792#else
11793static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11794 struct net_device *dev)
11795{
11796 int ret;
11797
11798 vos_ssr_protect(__func__);
11799 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11800 vos_ssr_unprotect(__func__);
11801
11802 return ret;
11803}
11804#endif
11805
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011806#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11807
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011808static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011809 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011810 struct cfg80211_ap_settings *params)
11811{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011812 hdd_adapter_t *pAdapter;
11813 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011814 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011815
11816 ENTER();
11817
Girish Gowlib143d7a2015-02-18 19:39:55 +053011818 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011819 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011821 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011822 return -ENODEV;
11823 }
11824
11825 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11826 if (NULL == pAdapter)
11827 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011829 "%s: HDD adapter is Null", __func__);
11830 return -ENODEV;
11831 }
11832
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011833 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11834 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11835 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011836 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11837 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011839 "%s: HDD adapter magic is invalid", __func__);
11840 return -ENODEV;
11841 }
11842
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011843 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11844
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011845 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011846 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011847 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011848 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011849 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011850 }
11851
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011852 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11853 __func__, hdd_device_modetoString(pAdapter->device_mode),
11854 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011855
11856 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011857 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011858 )
11859 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011860 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011861
11862 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011863
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011864 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011865 {
11866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11867 FL("already beacon info added to session(%d)"),
11868 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011869 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011870 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011871
Girish Gowlib143d7a2015-02-18 19:39:55 +053011872#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11873 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11874 &new,
11875 &params->beacon);
11876#else
11877 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11878 &new,
11879 &params->beacon,
11880 params->dtim_period);
11881#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011882
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011883 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011884 {
11885 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011886 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011887 return -EINVAL;
11888 }
11889 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011890#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011891 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11892#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11893 params->channel, params->channel_type);
11894#else
11895 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11896#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011897#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011898 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011899 params->ssid_len, params->hidden_ssid,
11900 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011901 }
11902
11903 EXIT();
11904 return status;
11905}
11906
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011907static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11908 struct net_device *dev,
11909 struct cfg80211_ap_settings *params)
11910{
11911 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011912
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011913 vos_ssr_protect(__func__);
11914 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11915 vos_ssr_unprotect(__func__);
11916
11917 return ret;
11918}
11919
11920static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011921 struct net_device *dev,
11922 struct cfg80211_beacon_data *params)
11923{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011925 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011926 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011927
11928 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011929
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011930 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11931 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11932 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011933 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011934 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011935
11936 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11937 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011938 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011939 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011940 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011941 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011942
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011943 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011944 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011945 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011946 {
11947 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011948
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011949 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011950
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011951 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011952 {
11953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11954 FL("session(%d) beacon data points to NULL"),
11955 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011956 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011957 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011958
11959 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11960
11961 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011962 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011963 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011964 return -EINVAL;
11965 }
11966
11967 pAdapter->sessionCtx.ap.beacon = new;
11968
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011969 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11970 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011971 }
11972
11973 EXIT();
11974 return status;
11975}
11976
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011977static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11978 struct net_device *dev,
11979 struct cfg80211_beacon_data *params)
11980{
11981 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011982
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011983 vos_ssr_protect(__func__);
11984 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11985 vos_ssr_unprotect(__func__);
11986
11987 return ret;
11988}
11989
11990#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011991
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011992static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 struct net_device *dev,
11994 struct bss_parameters *params)
11995{
11996 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011997 hdd_context_t *pHddCtx;
11998 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011999
12000 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012001
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012002 if (NULL == pAdapter)
12003 {
12004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12005 "%s: HDD adapter is Null", __func__);
12006 return -ENODEV;
12007 }
12008 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012009 ret = wlan_hdd_validate_context(pHddCtx);
12010 if (0 != ret)
12011 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012012 return ret;
12013 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12015 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12016 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12018 __func__, hdd_device_modetoString(pAdapter->device_mode),
12019 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012020
12021 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012023 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 {
12025 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12026 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012027 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012028 {
12029 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012030 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012031 }
12032
12033 EXIT();
12034 return 0;
12035}
12036
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012037static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12038 struct net_device *dev,
12039 struct bss_parameters *params)
12040{
12041 int ret;
12042
12043 vos_ssr_protect(__func__);
12044 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12045 vos_ssr_unprotect(__func__);
12046
12047 return ret;
12048}
Kiet Lam10841362013-11-01 11:36:50 +053012049/* FUNCTION: wlan_hdd_change_country_code_cd
12050* to wait for contry code completion
12051*/
12052void* wlan_hdd_change_country_code_cb(void *pAdapter)
12053{
12054 hdd_adapter_t *call_back_pAdapter = pAdapter;
12055 complete(&call_back_pAdapter->change_country_code);
12056 return NULL;
12057}
12058
Jeff Johnson295189b2012-06-20 16:38:30 -070012059/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012060 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012061 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12062 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012063int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012064 struct net_device *ndev,
12065 enum nl80211_iftype type,
12066 u32 *flags,
12067 struct vif_params *params
12068 )
12069{
12070 struct wireless_dev *wdev;
12071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012072 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012073 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012074 tCsrRoamProfile *pRoamProfile = NULL;
12075 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012076 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012077 eMib_dot11DesiredBssType connectedBssType;
12078 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012079 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012080
12081 ENTER();
12082
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012083 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012084 {
12085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12086 "%s: Adapter context is null", __func__);
12087 return VOS_STATUS_E_FAILURE;
12088 }
12089
12090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12091 if (!pHddCtx)
12092 {
12093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12094 "%s: HDD context is null", __func__);
12095 return VOS_STATUS_E_FAILURE;
12096 }
12097
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012098 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12099 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12100 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012101 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012102 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012104 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012105 }
12106
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12108 __func__, hdd_device_modetoString(pAdapter->device_mode),
12109 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012110
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012111 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12112 hddLog(VOS_TRACE_LEVEL_FATAL,
12113 "%s: STA + MON is in progress, cannot change interface",
12114 __func__);
12115 }
12116
Agarwal Ashish51325b52014-06-16 16:50:49 +053012117 if (vos_max_concurrent_connections_reached()) {
12118 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12119 return -EINVAL;
12120 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012121 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 wdev = ndev->ieee80211_ptr;
12123
12124#ifdef WLAN_BTAMP_FEATURE
12125 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12126 (NL80211_IFTYPE_ADHOC == type)||
12127 (NL80211_IFTYPE_AP == type)||
12128 (NL80211_IFTYPE_P2P_GO == type))
12129 {
12130 pHddCtx->isAmpAllowed = VOS_FALSE;
12131 // stop AMP traffic
12132 status = WLANBAP_StopAmp();
12133 if(VOS_STATUS_SUCCESS != status )
12134 {
12135 pHddCtx->isAmpAllowed = VOS_TRUE;
12136 hddLog(VOS_TRACE_LEVEL_FATAL,
12137 "%s: Failed to stop AMP", __func__);
12138 return -EINVAL;
12139 }
12140 }
12141#endif //WLAN_BTAMP_FEATURE
12142 /* Reset the current device mode bit mask*/
12143 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12144
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012145 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12146 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12147 (type == NL80211_IFTYPE_P2P_GO)))
12148 {
12149 /* Notify Mode change in case of concurrency.
12150 * Below function invokes TDLS teardown Functionality Since TDLS is
12151 * not Supported in case of concurrency i.e Once P2P session
12152 * is detected disable offchannel and teardown TDLS links
12153 */
12154 hddLog(LOG1,
12155 FL("Device mode = %d Interface type = %d"),
12156 pAdapter->device_mode, type);
12157 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12158 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012159
Jeff Johnson295189b2012-06-20 16:38:30 -070012160 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012162 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012163 )
12164 {
12165 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012166 if (!pWextState)
12167 {
12168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12169 "%s: pWextState is null", __func__);
12170 return VOS_STATUS_E_FAILURE;
12171 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012172 pRoamProfile = &pWextState->roamProfile;
12173 LastBSSType = pRoamProfile->BSSType;
12174
12175 switch (type)
12176 {
12177 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 hddLog(VOS_TRACE_LEVEL_INFO,
12180 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12181 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012182#ifdef WLAN_FEATURE_11AC
12183 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12184 {
12185 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12186 }
12187#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012189 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012191 //Check for sub-string p2p to confirm its a p2p interface
12192 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012193 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012194#ifdef FEATURE_WLAN_TDLS
12195 mutex_lock(&pHddCtx->tdls_lock);
12196 wlan_hdd_tdls_exit(pAdapter, TRUE);
12197 mutex_unlock(&pHddCtx->tdls_lock);
12198#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012199 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12200 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12201 }
12202 else
12203 {
12204 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012206 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012208
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 case NL80211_IFTYPE_ADHOC:
12210 hddLog(VOS_TRACE_LEVEL_INFO,
12211 "%s: setting interface Type to ADHOC", __func__);
12212 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12213 pRoamProfile->phyMode =
12214 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012215 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012217 hdd_set_ibss_ops( pAdapter );
12218 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012219
12220 status = hdd_sta_id_hash_attach(pAdapter);
12221 if (VOS_STATUS_SUCCESS != status) {
12222 hddLog(VOS_TRACE_LEVEL_ERROR,
12223 FL("Failed to initialize hash for IBSS"));
12224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 break;
12226
12227 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012228 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 {
12230 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12231 "%s: setting interface Type to %s", __func__,
12232 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12233
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012234 //Cancel any remain on channel for GO mode
12235 if (NL80211_IFTYPE_P2P_GO == type)
12236 {
12237 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12238 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012239 if (NL80211_IFTYPE_AP == type)
12240 {
12241 /* As Loading WLAN Driver one interface being created for p2p device
12242 * address. This will take one HW STA and the max number of clients
12243 * that can connect to softAP will be reduced by one. so while changing
12244 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12245 * interface as it is not required in SoftAP mode.
12246 */
12247
12248 // Get P2P Adapter
12249 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12250
12251 if (pP2pAdapter)
12252 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012253 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012254 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012255 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12256 }
12257 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012258 //Disable IMPS & BMPS for SAP/GO
12259 if(VOS_STATUS_E_FAILURE ==
12260 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12261 {
12262 //Fail to Exit BMPS
12263 VOS_ASSERT(0);
12264 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012265
12266 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12267
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012268#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012269
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012270 /* A Mutex Lock is introduced while changing the mode to
12271 * protect the concurrent access for the Adapters by TDLS
12272 * module.
12273 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012274 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012275#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012277 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012279 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12280 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012281#ifdef FEATURE_WLAN_TDLS
12282 mutex_unlock(&pHddCtx->tdls_lock);
12283#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012284 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12285 (pConfig->apRandomBssidEnabled))
12286 {
12287 /* To meet Android requirements create a randomized
12288 MAC address of the form 02:1A:11:Fx:xx:xx */
12289 get_random_bytes(&ndev->dev_addr[3], 3);
12290 ndev->dev_addr[0] = 0x02;
12291 ndev->dev_addr[1] = 0x1A;
12292 ndev->dev_addr[2] = 0x11;
12293 ndev->dev_addr[3] |= 0xF0;
12294 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12295 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012296 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12297 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012298 }
12299
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 hdd_set_ap_ops( pAdapter->dev );
12301
Kiet Lam10841362013-11-01 11:36:50 +053012302 /* This is for only SAP mode where users can
12303 * control country through ini.
12304 * P2P GO follows station country code
12305 * acquired during the STA scanning. */
12306 if((NL80211_IFTYPE_AP == type) &&
12307 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12308 {
12309 int status = 0;
12310 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12311 "%s: setting country code from INI ", __func__);
12312 init_completion(&pAdapter->change_country_code);
12313 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12314 (void *)(tSmeChangeCountryCallback)
12315 wlan_hdd_change_country_code_cb,
12316 pConfig->apCntryCode, pAdapter,
12317 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012318 eSIR_FALSE,
12319 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012320 if (eHAL_STATUS_SUCCESS == status)
12321 {
12322 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012323 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012324 &pAdapter->change_country_code,
12325 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012326 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012327 {
12328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012329 FL("SME Timed out while setting country code %ld"),
12330 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012331
12332 if (pHddCtx->isLogpInProgress)
12333 {
12334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12335 "%s: LOGP in Progress. Ignore!!!", __func__);
12336 return -EAGAIN;
12337 }
Kiet Lam10841362013-11-01 11:36:50 +053012338 }
12339 }
12340 else
12341 {
12342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012343 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012344 return -EINVAL;
12345 }
12346 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012347 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012348 if(status != VOS_STATUS_SUCCESS)
12349 {
12350 hddLog(VOS_TRACE_LEVEL_FATAL,
12351 "%s: Error initializing the ap mode", __func__);
12352 return -EINVAL;
12353 }
12354 hdd_set_conparam(1);
12355
Nirav Shah7e3c8132015-06-22 23:51:42 +053012356 status = hdd_sta_id_hash_attach(pAdapter);
12357 if (VOS_STATUS_SUCCESS != status)
12358 {
12359 hddLog(VOS_TRACE_LEVEL_ERROR,
12360 FL("Failed to initialize hash for AP"));
12361 return -EINVAL;
12362 }
12363
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 /*interface type changed update in wiphy structure*/
12365 if(wdev)
12366 {
12367 wdev->iftype = type;
12368 pHddCtx->change_iface = type;
12369 }
12370 else
12371 {
12372 hddLog(VOS_TRACE_LEVEL_ERROR,
12373 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12374 return -EINVAL;
12375 }
12376 goto done;
12377 }
12378
12379 default:
12380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12381 __func__);
12382 return -EOPNOTSUPP;
12383 }
12384 }
12385 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012387 )
12388 {
12389 switch(type)
12390 {
12391 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012392 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012394
12395 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012396#ifdef FEATURE_WLAN_TDLS
12397
12398 /* A Mutex Lock is introduced while changing the mode to
12399 * protect the concurrent access for the Adapters by TDLS
12400 * module.
12401 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012402 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012403#endif
c_hpothu002231a2015-02-05 14:58:51 +053012404 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012406 //Check for sub-string p2p to confirm its a p2p interface
12407 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012408 {
12409 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12410 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12411 }
12412 else
12413 {
12414 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012415 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012416 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012417
12418 /* set con_mode to STA only when no SAP concurrency mode */
12419 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12420 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12423 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012424#ifdef FEATURE_WLAN_TDLS
12425 mutex_unlock(&pHddCtx->tdls_lock);
12426#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012427 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 if( VOS_STATUS_SUCCESS != status )
12429 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012430 /* In case of JB, for P2P-GO, only change interface will be called,
12431 * This is the right place to enable back bmps_imps()
12432 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012433 if (pHddCtx->hdd_wlan_suspended)
12434 {
12435 hdd_set_pwrparams(pHddCtx);
12436 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012437 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 goto done;
12439 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012440 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012442 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12443 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012444 goto done;
12445 default:
12446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12447 __func__);
12448 return -EOPNOTSUPP;
12449
12450 }
12451
12452 }
12453 else
12454 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012455 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12456 __func__, hdd_device_modetoString(pAdapter->device_mode),
12457 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012458 return -EOPNOTSUPP;
12459 }
12460
12461
12462 if(pRoamProfile)
12463 {
12464 if ( LastBSSType != pRoamProfile->BSSType )
12465 {
12466 /*interface type changed update in wiphy structure*/
12467 wdev->iftype = type;
12468
12469 /*the BSS mode changed, We need to issue disconnect
12470 if connected or in IBSS disconnect state*/
12471 if ( hdd_connGetConnectedBssType(
12472 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12473 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12474 {
12475 /*need to issue a disconnect to CSR.*/
12476 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12477 if( eHAL_STATUS_SUCCESS ==
12478 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12479 pAdapter->sessionId,
12480 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12481 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012482 ret = wait_for_completion_interruptible_timeout(
12483 &pAdapter->disconnect_comp_var,
12484 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12485 if (ret <= 0)
12486 {
12487 hddLog(VOS_TRACE_LEVEL_ERROR,
12488 FL("wait on disconnect_comp_var failed %ld"), ret);
12489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 }
12491 }
12492 }
12493 }
12494
12495done:
12496 /*set bitmask based on updated value*/
12497 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012498
12499 /* Only STA mode support TM now
12500 * all other mode, TM feature should be disabled */
12501 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12502 (~VOS_STA & pHddCtx->concurrency_mode) )
12503 {
12504 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12505 }
12506
Jeff Johnson295189b2012-06-20 16:38:30 -070012507#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012508 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012509 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 {
12511 //we are ok to do AMP
12512 pHddCtx->isAmpAllowed = VOS_TRUE;
12513 }
12514#endif //WLAN_BTAMP_FEATURE
12515 EXIT();
12516 return 0;
12517}
12518
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012519/*
12520 * FUNCTION: wlan_hdd_cfg80211_change_iface
12521 * wrapper function to protect the actual implementation from SSR.
12522 */
12523int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12524 struct net_device *ndev,
12525 enum nl80211_iftype type,
12526 u32 *flags,
12527 struct vif_params *params
12528 )
12529{
12530 int ret;
12531
12532 vos_ssr_protect(__func__);
12533 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12534 vos_ssr_unprotect(__func__);
12535
12536 return ret;
12537}
12538
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012539#ifdef FEATURE_WLAN_TDLS
12540static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012541 struct net_device *dev,
12542#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12543 const u8 *mac,
12544#else
12545 u8 *mac,
12546#endif
12547 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012548{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012549 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012550 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012551 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012552 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012553 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012554 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012555
12556 ENTER();
12557
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012558 if (!dev) {
12559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12560 return -EINVAL;
12561 }
12562
12563 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12564 if (!pAdapter) {
12565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12566 return -EINVAL;
12567 }
12568
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012569 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012570 {
12571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12572 "Invalid arguments");
12573 return -EINVAL;
12574 }
Hoonki Lee27511902013-03-14 18:19:06 -070012575
12576 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12577 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12578 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012580 "%s: TDLS mode is disabled OR not enabled in FW."
12581 MAC_ADDRESS_STR " Request declined.",
12582 __func__, MAC_ADDR_ARRAY(mac));
12583 return -ENOTSUPP;
12584 }
12585
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012586 if (pHddCtx->isLogpInProgress)
12587 {
12588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12589 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012590 wlan_hdd_tdls_set_link_status(pAdapter,
12591 mac,
12592 eTDLS_LINK_IDLE,
12593 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012594 return -EBUSY;
12595 }
12596
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012597 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012598 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012599
12600 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012602 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12603 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012604 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012605 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012606 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012607
12608 /* in add station, we accept existing valid staId if there is */
12609 if ((0 == update) &&
12610 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12611 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012612 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012614 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012615 " link_status %d. staId %d. add station ignored.",
12616 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012617 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012618 return 0;
12619 }
12620 /* in change station, we accept only when staId is valid */
12621 if ((1 == update) &&
12622 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12623 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12624 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012625 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012627 "%s: " MAC_ADDRESS_STR
12628 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012629 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12630 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12631 mutex_unlock(&pHddCtx->tdls_lock);
12632 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012633 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012634 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012635
12636 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012637 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012638 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12640 "%s: " MAC_ADDRESS_STR
12641 " TDLS setup is ongoing. Request declined.",
12642 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012643 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012644 }
12645
12646 /* first to check if we reached to maximum supported TDLS peer.
12647 TODO: for now, return -EPERM looks working fine,
12648 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012649 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12650 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012651 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12653 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012654 " TDLS Max peer already connected. Request declined."
12655 " Num of peers (%d), Max allowed (%d).",
12656 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12657 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012658 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012659 }
12660 else
12661 {
12662 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012663 mutex_lock(&pHddCtx->tdls_lock);
12664 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012665 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012666 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012667 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12669 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12670 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012671 return -EPERM;
12672 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012673 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012674 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012675 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012676 wlan_hdd_tdls_set_link_status(pAdapter,
12677 mac,
12678 eTDLS_LINK_CONNECTING,
12679 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012680
Jeff Johnsond75fe012013-04-06 10:53:06 -070012681 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012682 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012683 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012685 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012686 if(StaParams->htcap_present)
12687 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012689 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012691 "ht_capa->extended_capabilities: %0x",
12692 StaParams->HTCap.extendedHtCapInfo);
12693 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012695 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012697 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012698 if(StaParams->vhtcap_present)
12699 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012701 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12702 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12703 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12704 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012705 {
12706 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012708 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012710 "[%d]: %x ", i, StaParams->supported_rates[i]);
12711 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012712 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012713 else if ((1 == update) && (NULL == StaParams))
12714 {
12715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12716 "%s : update is true, but staParams is NULL. Error!", __func__);
12717 return -EPERM;
12718 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012719
12720 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12721
12722 if (!update)
12723 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012724 /*Before adding sta make sure that device exited from BMPS*/
12725 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12726 {
12727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12728 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12729 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12730 if (status != VOS_STATUS_SUCCESS) {
12731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12732 }
12733 }
12734
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012735 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012736 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012737 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012738 hddLog(VOS_TRACE_LEVEL_ERROR,
12739 FL("Failed to add TDLS peer STA. Enable Bmps"));
12740 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012741 return -EPERM;
12742 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012743 }
12744 else
12745 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012746 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012747 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012748 if (ret != eHAL_STATUS_SUCCESS) {
12749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12750 return -EPERM;
12751 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012752 }
12753
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012754 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012755 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12756
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012757 mutex_lock(&pHddCtx->tdls_lock);
12758 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12759
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012760 if ((pTdlsPeer != NULL) &&
12761 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012762 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012763 hddLog(VOS_TRACE_LEVEL_ERROR,
12764 FL("peer link status %u"), pTdlsPeer->link_status);
12765 mutex_unlock(&pHddCtx->tdls_lock);
12766 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012767 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012768 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012769
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012770 if (ret <= 0)
12771 {
12772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12773 "%s: timeout waiting for tdls add station indication %ld",
12774 __func__, ret);
12775 goto error;
12776 }
12777
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012778 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12779 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012781 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012782 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012783 }
12784
12785 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012786
12787error:
Atul Mittal115287b2014-07-08 13:26:33 +053012788 wlan_hdd_tdls_set_link_status(pAdapter,
12789 mac,
12790 eTDLS_LINK_IDLE,
12791 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012792 return -EPERM;
12793
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012794}
12795#endif
12796
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012797VOS_STATUS wlan_hdd_send_sta_authorized_event(
12798 hdd_adapter_t *adapter,
12799 hdd_context_t *hdd_ctx,
12800 const v_MACADDR_t *mac_addr)
12801{
12802 struct sk_buff *vendor_event;
12803 uint32_t sta_flags = 0;
12804 VOS_STATUS status;
12805
12806 ENTER();
12807
12808 if (!hdd_ctx) {
12809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12810 return -EINVAL;
12811 }
12812
12813 vendor_event =
12814 cfg80211_vendor_event_alloc(
12815 hdd_ctx->wiphy, &adapter->wdev, sizeof(sta_flags) +
12816 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12817 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12818 GFP_KERNEL);
12819 if (!vendor_event) {
12820 hddLog(VOS_TRACE_LEVEL_ERROR,
12821 FL("cfg80211_vendor_event_alloc failed"));
12822 return -EINVAL;
12823 }
12824
12825 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12826
12827 status = nla_put_u32(vendor_event,
12828 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12829 sta_flags);
12830 if (status) {
12831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12832 kfree_skb(vendor_event);
12833 return VOS_STATUS_E_FAILURE;
12834 }
12835 status = nla_put(vendor_event,
12836 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12837 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12838 if (status) {
12839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12840 kfree_skb(vendor_event);
12841 return VOS_STATUS_E_FAILURE;
12842 }
12843
12844 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
12845
12846 EXIT();
12847 return 0;
12848}
12849
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012850static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012851 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012852#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12853 const u8 *mac,
12854#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012857 struct station_parameters *params)
12858{
12859 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012860 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012861 hdd_context_t *pHddCtx;
12862 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012863 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012864 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012865#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012866 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012867 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012868 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012869 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012870#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012871
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012872 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012873
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012874 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012875 if ((NULL == pAdapter))
12876 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012878 "invalid adapter ");
12879 return -EINVAL;
12880 }
12881
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012882 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12883 TRACE_CODE_HDD_CHANGE_STATION,
12884 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012885 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012886
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012887 ret = wlan_hdd_validate_context(pHddCtx);
12888 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012889 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012890 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012891 }
12892
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12894
12895 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012896 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12898 "invalid HDD station context");
12899 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012900 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012901 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12902
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012903 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12904 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012906 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012907 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012908 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012909 WLANTL_STA_AUTHENTICATED);
12910
Gopichand Nakkala29149562013-05-10 21:43:41 +053012911 if (status != VOS_STATUS_SUCCESS)
12912 {
12913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12914 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12915 return -EINVAL;
12916 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012917 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
12918 &STAMacAddress);
12919 if (status != VOS_STATUS_SUCCESS)
12920 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012921 }
12922 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012923 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12924 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012925#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012926 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12927 StaParams.capability = params->capability;
12928 StaParams.uapsd_queues = params->uapsd_queues;
12929 StaParams.max_sp = params->max_sp;
12930
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012931 /* Convert (first channel , number of channels) tuple to
12932 * the total list of channels. This goes with the assumption
12933 * that if the first channel is < 14, then the next channels
12934 * are an incremental of 1 else an incremental of 4 till the number
12935 * of channels.
12936 */
12937 if (0 != params->supported_channels_len) {
12938 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12939 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12940 {
12941 int wifi_chan_index;
12942 StaParams.supported_channels[j] = params->supported_channels[i];
12943 wifi_chan_index =
12944 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12945 no_of_channels = params->supported_channels[i+1];
12946 for(k=1; k <= no_of_channels; k++)
12947 {
12948 StaParams.supported_channels[j+1] =
12949 StaParams.supported_channels[j] + wifi_chan_index;
12950 j+=1;
12951 }
12952 }
12953 StaParams.supported_channels_len = j;
12954 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012955 if (params->supported_oper_classes_len >
12956 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12958 "received oper classes:%d, resetting it to max supported %d",
12959 params->supported_oper_classes_len,
12960 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12961 params->supported_oper_classes_len =
12962 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12963 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012964 vos_mem_copy(StaParams.supported_oper_classes,
12965 params->supported_oper_classes,
12966 params->supported_oper_classes_len);
12967 StaParams.supported_oper_classes_len =
12968 params->supported_oper_classes_len;
12969
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012970 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12972 "received extn capabilities:%d, resetting it to max supported",
12973 params->ext_capab_len);
12974 params->ext_capab_len = sizeof(StaParams.extn_capability);
12975 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012976 if (0 != params->ext_capab_len)
12977 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012978 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012979
12980 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012981 {
12982 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012983 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012984 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012985
12986 StaParams.supported_rates_len = params->supported_rates_len;
12987
12988 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12989 * The supported_rates array , for all the structures propogating till Add Sta
12990 * to the firmware has to be modified , if the supplicant (ieee80211) is
12991 * modified to send more rates.
12992 */
12993
12994 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12995 */
12996 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12997 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12998
12999 if (0 != StaParams.supported_rates_len) {
13000 int i = 0;
13001 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13002 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013004 "Supported Rates with Length %d", StaParams.supported_rates_len);
13005 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013007 "[%d]: %0x", i, StaParams.supported_rates[i]);
13008 }
13009
13010 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013011 {
13012 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013013 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013014 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013015
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013016 if (0 != params->ext_capab_len ) {
13017 /*Define A Macro : TODO Sunil*/
13018 if ((1<<4) & StaParams.extn_capability[3]) {
13019 isBufSta = 1;
13020 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013021 /* TDLS Channel Switching Support */
13022 if ((1<<6) & StaParams.extn_capability[3]) {
13023 isOffChannelSupported = 1;
13024 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013025 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013026
13027 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013028 (params->ht_capa || params->vht_capa ||
13029 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013030 /* TDLS Peer is WME/QoS capable */
13031 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013032
13033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13034 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13035 __func__, isQosWmmSta, StaParams.htcap_present);
13036
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013037 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13038 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013039 isOffChannelSupported,
13040 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013041
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013042 if (VOS_STATUS_SUCCESS != status) {
13043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13044 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13045 return -EINVAL;
13046 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013047 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13048
13049 if (VOS_STATUS_SUCCESS != status) {
13050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13051 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13052 return -EINVAL;
13053 }
13054 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013055#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013056 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013057 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013058 return status;
13059}
13060
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13062static int wlan_hdd_change_station(struct wiphy *wiphy,
13063 struct net_device *dev,
13064 const u8 *mac,
13065 struct station_parameters *params)
13066#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013067static int wlan_hdd_change_station(struct wiphy *wiphy,
13068 struct net_device *dev,
13069 u8 *mac,
13070 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013071#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013072{
13073 int ret;
13074
13075 vos_ssr_protect(__func__);
13076 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13077 vos_ssr_unprotect(__func__);
13078
13079 return ret;
13080}
13081
Jeff Johnson295189b2012-06-20 16:38:30 -070013082/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013083 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013084 * This function is used to initialize the key information
13085 */
13086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013087static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013088 struct net_device *ndev,
13089 u8 key_index, bool pairwise,
13090 const u8 *mac_addr,
13091 struct key_params *params
13092 )
13093#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013094static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013095 struct net_device *ndev,
13096 u8 key_index, const u8 *mac_addr,
13097 struct key_params *params
13098 )
13099#endif
13100{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013101 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013102 tCsrRoamSetKey setKey;
13103 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013104 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013105 v_U32_t roamId= 0xFF;
13106 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 hdd_hostapd_state_t *pHostapdState;
13108 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013109 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013110 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013111 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013112 v_MACADDR_t *peerMacAddr;
13113 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013114 uint8_t staid = HDD_MAX_STA_COUNT;
13115 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013116
13117 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013118
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013119 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13120 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13121 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013122 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13123 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013124 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013125 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013126 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013127 }
13128
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013129 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13130 __func__, hdd_device_modetoString(pAdapter->device_mode),
13131 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013132
13133 if (CSR_MAX_NUM_KEY <= key_index)
13134 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013136 key_index);
13137
13138 return -EINVAL;
13139 }
13140
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013141 if (CSR_MAX_KEY_LEN < params->key_len)
13142 {
13143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13144 params->key_len);
13145
13146 return -EINVAL;
13147 }
13148
Jingxiang Gec438aea2017-10-26 16:44:00 +080013149 if (CSR_MAX_RSC_LEN < params->seq_len)
13150 {
13151 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13152 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013153
13154 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013155 }
13156
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013157 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013158 "%s: called with key index = %d & key length %d & seq length %d",
13159 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013160
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013161 peerMacAddr = (v_MACADDR_t *)mac_addr;
13162
Jeff Johnson295189b2012-06-20 16:38:30 -070013163 /*extract key idx, key len and key*/
13164 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13165 setKey.keyId = key_index;
13166 setKey.keyLength = params->key_len;
13167 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013168 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013169
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013170 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 {
13172 case WLAN_CIPHER_SUITE_WEP40:
13173 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13174 break;
13175
13176 case WLAN_CIPHER_SUITE_WEP104:
13177 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13178 break;
13179
13180 case WLAN_CIPHER_SUITE_TKIP:
13181 {
13182 u8 *pKey = &setKey.Key[0];
13183 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13184
13185 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13186
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013187 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013188
13189 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013190 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013191 |--------------|----------|----------|
13192 <---16bytes---><--8bytes--><--8bytes-->
13193
13194 */
13195 /*Sme expects the 32 bytes key to be in the below order
13196
13197 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013198 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013199 |--------------|----------|----------|
13200 <---16bytes---><--8bytes--><--8bytes-->
13201 */
13202 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013203 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013204
13205 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013206 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013207
13208 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013209 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013210
13211
13212 break;
13213 }
13214
13215 case WLAN_CIPHER_SUITE_CCMP:
13216 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13217 break;
13218
13219#ifdef FEATURE_WLAN_WAPI
13220 case WLAN_CIPHER_SUITE_SMS4:
13221 {
13222 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13223 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13224 params->key, params->key_len);
13225 return 0;
13226 }
13227#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013228
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013229#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 case WLAN_CIPHER_SUITE_KRK:
13231 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13232 break;
13233#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013234
13235#ifdef WLAN_FEATURE_11W
13236 case WLAN_CIPHER_SUITE_AES_CMAC:
13237 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013238 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013239#endif
13240
Jeff Johnson295189b2012-06-20 16:38:30 -070013241 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013243 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013244 status = -EOPNOTSUPP;
13245 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 }
13247
13248 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13249 __func__, setKey.encType);
13250
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013251 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013252#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13253 (!pairwise)
13254#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013255 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013256#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013257 )
13258 {
13259 /* set group key*/
13260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13261 "%s- %d: setting Broadcast key",
13262 __func__, __LINE__);
13263 setKey.keyDirection = eSIR_RX_ONLY;
13264 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13265 }
13266 else
13267 {
13268 /* set pairwise key*/
13269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13270 "%s- %d: setting pairwise key",
13271 __func__, __LINE__);
13272 setKey.keyDirection = eSIR_TX_RX;
13273 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013274 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013275 }
13276 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13277 {
13278 setKey.keyDirection = eSIR_TX_RX;
13279 /*Set the group key*/
13280 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13281 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013282
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013283 if ( 0 != status )
13284 {
13285 hddLog(VOS_TRACE_LEVEL_ERROR,
13286 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013287 status = -EINVAL;
13288 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013289 }
13290 /*Save the keys here and call sme_RoamSetKey for setting
13291 the PTK after peer joins the IBSS network*/
13292 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13293 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013294 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013295 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013296 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13297 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13298 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013299 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013300 if( pHostapdState->bssState == BSS_START )
13301 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013302 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13303 vos_status = wlan_hdd_check_ula_done(pAdapter);
13304
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013305 if (peerMacAddr && (pairwise_set_key == true))
13306 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013307
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013308 if ( vos_status != VOS_STATUS_SUCCESS )
13309 {
13310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13311 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13312 __LINE__, vos_status );
13313
13314 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13315
13316 status = -EINVAL;
13317 goto end;
13318 }
13319
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13321
13322 if ( status != eHAL_STATUS_SUCCESS )
13323 {
13324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13325 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13326 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013327 status = -EINVAL;
13328 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 }
13330 }
13331
13332 /* Saving WEP keys */
13333 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13334 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13335 {
13336 //Save the wep key in ap context. Issue setkey after the BSS is started.
13337 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13338 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13339 }
13340 else
13341 {
13342 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013343 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13345 }
13346 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013347 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13348 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 {
13350 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13351 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13352
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13354 if (!pairwise)
13355#else
13356 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13357#endif
13358 {
13359 /* set group key*/
13360 if (pHddStaCtx->roam_info.deferKeyComplete)
13361 {
13362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13363 "%s- %d: Perform Set key Complete",
13364 __func__, __LINE__);
13365 hdd_PerformRoamSetKeyComplete(pAdapter);
13366 }
13367 }
13368
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013369 if (pairwise_set_key == true)
13370 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013371
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13373
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013374 pWextState->roamProfile.Keys.defaultIndex = key_index;
13375
13376
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013377 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 params->key, params->key_len);
13379
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013380
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13382
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013383 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013385 __func__, setKey.peerMac[0], setKey.peerMac[1],
13386 setKey.peerMac[2], setKey.peerMac[3],
13387 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013388 setKey.keyDirection);
13389
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013390 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013391
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013392 if ( vos_status != VOS_STATUS_SUCCESS )
13393 {
13394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013395 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13396 __LINE__, vos_status );
13397
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013398 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013399
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013400 status = -EINVAL;
13401 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013402
13403 }
13404
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013405#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013406 /* The supplicant may attempt to set the PTK once pre-authentication
13407 is done. Save the key in the UMAC and include it in the ADD BSS
13408 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013409 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013410 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013411 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013412 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13413 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013414 status = 0;
13415 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013416 }
13417 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13418 {
13419 hddLog(VOS_TRACE_LEVEL_ERROR,
13420 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013421 status = -EINVAL;
13422 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013423 }
13424#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013425
13426 /* issue set key request to SME*/
13427 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13428 pAdapter->sessionId, &setKey, &roamId );
13429
13430 if ( 0 != status )
13431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013432 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013433 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13434 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013435 status = -EINVAL;
13436 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 }
13438
13439
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013440 /* in case of IBSS as there was no information available about WEP keys during
13441 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013443 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13444 !( ( IW_AUTH_KEY_MGMT_802_1X
13445 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013446 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13447 )
13448 &&
13449 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13450 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13451 )
13452 )
13453 {
13454 setKey.keyDirection = eSIR_RX_ONLY;
13455 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13456
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013457 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013459 __func__, setKey.peerMac[0], setKey.peerMac[1],
13460 setKey.peerMac[2], setKey.peerMac[3],
13461 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 setKey.keyDirection);
13463
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013464 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013465 pAdapter->sessionId, &setKey, &roamId );
13466
13467 if ( 0 != status )
13468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013469 hddLog(VOS_TRACE_LEVEL_ERROR,
13470 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013471 __func__, status);
13472 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013473 status = -EINVAL;
13474 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 }
13476 }
13477 }
13478
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013479 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013480 for (i = 0; i < params->seq_len; i++) {
13481 rsc_counter |= (params->seq[i] << i*8);
13482 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013483 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13484 }
13485
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013486end:
13487 /* Need to clear any trace of key value in the memory.
13488 * Thus zero out the memory even though it is local
13489 * variable.
13490 */
13491 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013492 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013493 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013494}
13495
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13497static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13498 struct net_device *ndev,
13499 u8 key_index, bool pairwise,
13500 const u8 *mac_addr,
13501 struct key_params *params
13502 )
13503#else
13504static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13505 struct net_device *ndev,
13506 u8 key_index, const u8 *mac_addr,
13507 struct key_params *params
13508 )
13509#endif
13510{
13511 int ret;
13512 vos_ssr_protect(__func__);
13513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13514 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13515 mac_addr, params);
13516#else
13517 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13518 params);
13519#endif
13520 vos_ssr_unprotect(__func__);
13521
13522 return ret;
13523}
13524
Jeff Johnson295189b2012-06-20 16:38:30 -070013525/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013526 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 * This function is used to get the key information
13528 */
13529#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013530static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013531 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013532 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013533 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 const u8 *mac_addr, void *cookie,
13535 void (*callback)(void *cookie, struct key_params*)
13536 )
13537#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013538static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013539 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013540 struct net_device *ndev,
13541 u8 key_index, const u8 *mac_addr, void *cookie,
13542 void (*callback)(void *cookie, struct key_params*)
13543 )
13544#endif
13545{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013547 hdd_wext_state_t *pWextState = NULL;
13548 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013549 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013550 hdd_context_t *pHddCtx;
13551 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013552
13553 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013554
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013555 if (NULL == pAdapter)
13556 {
13557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13558 "%s: HDD adapter is Null", __func__);
13559 return -ENODEV;
13560 }
13561
13562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13563 ret = wlan_hdd_validate_context(pHddCtx);
13564 if (0 != ret)
13565 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013566 return ret;
13567 }
13568
13569 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13570 pRoamProfile = &(pWextState->roamProfile);
13571
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013572 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13573 __func__, hdd_device_modetoString(pAdapter->device_mode),
13574 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013575
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 memset(&params, 0, sizeof(params));
13577
13578 if (CSR_MAX_NUM_KEY <= key_index)
13579 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013583
13584 switch(pRoamProfile->EncryptionType.encryptionType[0])
13585 {
13586 case eCSR_ENCRYPT_TYPE_NONE:
13587 params.cipher = IW_AUTH_CIPHER_NONE;
13588 break;
13589
13590 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13591 case eCSR_ENCRYPT_TYPE_WEP40:
13592 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13593 break;
13594
13595 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13596 case eCSR_ENCRYPT_TYPE_WEP104:
13597 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13598 break;
13599
13600 case eCSR_ENCRYPT_TYPE_TKIP:
13601 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13602 break;
13603
13604 case eCSR_ENCRYPT_TYPE_AES:
13605 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13606 break;
13607
13608 default:
13609 params.cipher = IW_AUTH_CIPHER_NONE;
13610 break;
13611 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013612
c_hpothuaaf19692014-05-17 17:01:48 +053013613 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13614 TRACE_CODE_HDD_CFG80211_GET_KEY,
13615 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013616
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13618 params.seq_len = 0;
13619 params.seq = NULL;
13620 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13621 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013622 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 return 0;
13624}
13625
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13627static int wlan_hdd_cfg80211_get_key(
13628 struct wiphy *wiphy,
13629 struct net_device *ndev,
13630 u8 key_index, bool pairwise,
13631 const u8 *mac_addr, void *cookie,
13632 void (*callback)(void *cookie, struct key_params*)
13633 )
13634#else
13635static int wlan_hdd_cfg80211_get_key(
13636 struct wiphy *wiphy,
13637 struct net_device *ndev,
13638 u8 key_index, const u8 *mac_addr, void *cookie,
13639 void (*callback)(void *cookie, struct key_params*)
13640 )
13641#endif
13642{
13643 int ret;
13644
13645 vos_ssr_protect(__func__);
13646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13647 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13648 mac_addr, cookie, callback);
13649#else
13650 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13651 callback);
13652#endif
13653 vos_ssr_unprotect(__func__);
13654
13655 return ret;
13656}
13657
Jeff Johnson295189b2012-06-20 16:38:30 -070013658/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013659 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 * This function is used to delete the key information
13661 */
13662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013663static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013664 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013665 u8 key_index,
13666 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 const u8 *mac_addr
13668 )
13669#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013670static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 struct net_device *ndev,
13672 u8 key_index,
13673 const u8 *mac_addr
13674 )
13675#endif
13676{
13677 int status = 0;
13678
13679 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013680 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013681 //it is observed that this is invalidating peer
13682 //key index whenever re-key is done. This is affecting data link.
13683 //It should be ok to ignore del_key.
13684#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013685 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13686 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13688 tCsrRoamSetKey setKey;
13689 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013690
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 ENTER();
13692
13693 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13694 __func__,pAdapter->device_mode);
13695
13696 if (CSR_MAX_NUM_KEY <= key_index)
13697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 key_index);
13700
13701 return -EINVAL;
13702 }
13703
13704 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13705 setKey.keyId = key_index;
13706
13707 if (mac_addr)
13708 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13709 else
13710 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13711
13712 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13713
13714 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013716 )
13717 {
13718
13719 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13721 if( pHostapdState->bssState == BSS_START)
13722 {
13723 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013724
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 if ( status != eHAL_STATUS_SUCCESS )
13726 {
13727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13728 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13729 __LINE__, status );
13730 }
13731 }
13732 }
13733 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013734 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 )
13736 {
13737 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13738
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013739 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13740
13741 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013743 __func__, setKey.peerMac[0], setKey.peerMac[1],
13744 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013745 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746 if(pAdapter->sessionCtx.station.conn_info.connState ==
13747 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013749 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 if ( 0 != status )
13753 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013754 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013755 "%s: sme_RoamSetKey failure, returned %d",
13756 __func__, status);
13757 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13758 return -EINVAL;
13759 }
13760 }
13761 }
13762#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013763 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013764 return status;
13765}
13766
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13768static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13769 struct net_device *ndev,
13770 u8 key_index,
13771 bool pairwise,
13772 const u8 *mac_addr
13773 )
13774#else
13775static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13776 struct net_device *ndev,
13777 u8 key_index,
13778 const u8 *mac_addr
13779 )
13780#endif
13781{
13782 int ret;
13783
13784 vos_ssr_protect(__func__);
13785#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13786 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13787 mac_addr);
13788#else
13789 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13790#endif
13791 vos_ssr_unprotect(__func__);
13792
13793 return ret;
13794}
13795
Jeff Johnson295189b2012-06-20 16:38:30 -070013796/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013797 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013798 * This function is used to set the default tx key index
13799 */
13800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013801static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 struct net_device *ndev,
13803 u8 key_index,
13804 bool unicast, bool multicast)
13805#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013806static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013807 struct net_device *ndev,
13808 u8 key_index)
13809#endif
13810{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013812 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013813 hdd_wext_state_t *pWextState;
13814 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013815 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013816
13817 ENTER();
13818
Gopichand Nakkala29149562013-05-10 21:43:41 +053013819 if ((NULL == pAdapter))
13820 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013822 "invalid adapter");
13823 return -EINVAL;
13824 }
13825
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013826 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13827 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13828 pAdapter->sessionId, key_index));
13829
Gopichand Nakkala29149562013-05-10 21:43:41 +053013830 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13831 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13832
13833 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13834 {
13835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13836 "invalid Wext state or HDD context");
13837 return -EINVAL;
13838 }
13839
Arif Hussain6d2a3322013-11-17 19:50:10 -080013840 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013842
Jeff Johnson295189b2012-06-20 16:38:30 -070013843 if (CSR_MAX_NUM_KEY <= key_index)
13844 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013845 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013846 key_index);
13847
13848 return -EINVAL;
13849 }
13850
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013851 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13852 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013853 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013854 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013855 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013856 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013857
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013860 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013862 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013863 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013864#ifdef FEATURE_WLAN_WAPI
13865 (eCSR_ENCRYPT_TYPE_WPI !=
13866 pHddStaCtx->conn_info.ucEncryptionType) &&
13867#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013869 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013870 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871 {
13872 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013874
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 tCsrRoamSetKey setKey;
13876 v_U32_t roamId= 0xFF;
13877 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013878
13879 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013881
Jeff Johnson295189b2012-06-20 16:38:30 -070013882 Keys->defaultIndex = (u8)key_index;
13883 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13884 setKey.keyId = key_index;
13885 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013886
13887 vos_mem_copy(&setKey.Key[0],
13888 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013890
Gopichand Nakkala29149562013-05-10 21:43:41 +053013891 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013892
13893 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 &pHddStaCtx->conn_info.bssId[0],
13895 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896
Gopichand Nakkala29149562013-05-10 21:43:41 +053013897 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13898 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13899 eCSR_ENCRYPT_TYPE_WEP104)
13900 {
13901 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13902 even though ap is configured for WEP-40 encryption. In this canse the key length
13903 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13904 type(104) and switching encryption type to 40*/
13905 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13906 eCSR_ENCRYPT_TYPE_WEP40;
13907 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13908 eCSR_ENCRYPT_TYPE_WEP40;
13909 }
13910
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013911 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013915 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013917
Jeff Johnson295189b2012-06-20 16:38:30 -070013918 if ( 0 != status )
13919 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920 hddLog(VOS_TRACE_LEVEL_ERROR,
13921 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 status);
13923 return -EINVAL;
13924 }
13925 }
13926 }
13927
13928 /* In SoftAp mode setting key direction for default mode */
13929 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13930 {
13931 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13932 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13933 (eCSR_ENCRYPT_TYPE_AES !=
13934 pWextState->roamProfile.EncryptionType.encryptionType[0])
13935 )
13936 {
13937 /* Saving key direction for default key index to TX default */
13938 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13939 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13940 }
13941 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013942 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 return status;
13944}
13945
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13947static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13948 struct net_device *ndev,
13949 u8 key_index,
13950 bool unicast, bool multicast)
13951#else
13952static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13953 struct net_device *ndev,
13954 u8 key_index)
13955#endif
13956{
13957 int ret;
13958 vos_ssr_protect(__func__);
13959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13960 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13961 multicast);
13962#else
13963 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13964#endif
13965 vos_ssr_unprotect(__func__);
13966
13967 return ret;
13968}
13969
Jeff Johnson295189b2012-06-20 16:38:30 -070013970/*
13971 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13972 * This function is used to inform the BSS details to nl80211 interface.
13973 */
13974static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13975 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13976{
13977 struct net_device *dev = pAdapter->dev;
13978 struct wireless_dev *wdev = dev->ieee80211_ptr;
13979 struct wiphy *wiphy = wdev->wiphy;
13980 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13981 int chan_no;
13982 int ie_length;
13983 const char *ie;
13984 unsigned int freq;
13985 struct ieee80211_channel *chan;
13986 int rssi = 0;
13987 struct cfg80211_bss *bss = NULL;
13988
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 if( NULL == pBssDesc )
13990 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013991 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 return bss;
13993 }
13994
13995 chan_no = pBssDesc->channelId;
13996 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13997 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13998
13999 if( NULL == ie )
14000 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014001 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014002 return bss;
14003 }
14004
14005#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14006 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14007 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014008 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 }
14010 else
14011 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014012 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 }
14014#else
14015 freq = ieee80211_channel_to_frequency(chan_no);
14016#endif
14017
14018 chan = __ieee80211_get_channel(wiphy, freq);
14019
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014020 if (!chan) {
14021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14022 return NULL;
14023 }
14024
Abhishek Singhaee43942014-06-16 18:55:47 +053014025 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014026
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014027 return cfg80211_inform_bss(wiphy, chan,
14028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14029 CFG80211_BSS_FTYPE_UNKNOWN,
14030#endif
14031 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014032 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014033 pBssDesc->capabilityInfo,
14034 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014035 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014036}
14037
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014038/*
14039 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14040 * interface that BSS might have been lost.
14041 * @pAdapter: adaptor
14042 * @bssid: bssid which might have been lost
14043 *
14044 * Return: bss which is unlinked from kernel cache
14045 */
14046struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14047 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14048{
14049 struct net_device *dev = pAdapter->dev;
14050 struct wireless_dev *wdev = dev->ieee80211_ptr;
14051 struct wiphy *wiphy = wdev->wiphy;
14052 struct cfg80211_bss *bss = NULL;
14053
Abhishek Singh5a597e62016-12-05 15:16:30 +053014054 bss = hdd_get_bss_entry(wiphy,
14055 NULL, bssid,
14056 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014057 if (bss == NULL) {
14058 hddLog(LOGE, FL("BSS not present"));
14059 } else {
14060 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14061 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14062 cfg80211_unlink_bss(wiphy, bss);
14063 }
14064 return bss;
14065}
Jeff Johnson295189b2012-06-20 16:38:30 -070014066
14067
14068/*
14069 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14070 * This function is used to inform the BSS details to nl80211 interface.
14071 */
14072struct cfg80211_bss*
14073wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14074 tSirBssDescription *bss_desc
14075 )
14076{
14077 /*
14078 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14079 already exists in bss data base of cfg80211 for that particular BSS ID.
14080 Using cfg80211_inform_bss_frame to update the bss entry instead of
14081 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14082 now there is no possibility to get the mgmt(probe response) frame from PE,
14083 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14084 cfg80211_inform_bss_frame.
14085 */
14086 struct net_device *dev = pAdapter->dev;
14087 struct wireless_dev *wdev = dev->ieee80211_ptr;
14088 struct wiphy *wiphy = wdev->wiphy;
14089 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014090#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14091 qcom_ie_age *qie_age = NULL;
14092 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14093#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014095#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014096 const char *ie =
14097 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14098 unsigned int freq;
14099 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014100 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014101 struct cfg80211_bss *bss_status = NULL;
14102 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14103 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014104 hdd_context_t *pHddCtx;
14105 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014106#ifdef WLAN_OPEN_SOURCE
14107 struct timespec ts;
14108#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014109
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014110
Wilson Yangf80a0542013-10-07 13:02:37 -070014111 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14112 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014113 if (0 != status)
14114 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014115 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014116 }
14117
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014118 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014119 if (!mgmt)
14120 {
14121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14122 "%s: memory allocation failed ", __func__);
14123 return NULL;
14124 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014125
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014127
14128#ifdef WLAN_OPEN_SOURCE
14129 /* Android does not want the timestamp from the frame.
14130 Instead it wants a monotonic increasing value */
14131 get_monotonic_boottime(&ts);
14132 mgmt->u.probe_resp.timestamp =
14133 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14134#else
14135 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014136 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14137 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014138
14139#endif
14140
Jeff Johnson295189b2012-06-20 16:38:30 -070014141 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14142 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014143
14144#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14145 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14146 /* Assuming this is the last IE, copy at the end */
14147 ie_length -=sizeof(qcom_ie_age);
14148 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14149 qie_age->element_id = QCOM_VENDOR_IE_ID;
14150 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14151 qie_age->oui_1 = QCOM_OUI1;
14152 qie_age->oui_2 = QCOM_OUI2;
14153 qie_age->oui_3 = QCOM_OUI3;
14154 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014155 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14156 * bss related timestamp is in units of ms. Due to this when scan results
14157 * are sent to lowi the scan age is high.To address this, send age in units
14158 * of 1/10 ms.
14159 */
14160 qie_age->age = (vos_timer_get_system_time() -
14161 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014162#endif
14163
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014165 if (bss_desc->fProbeRsp)
14166 {
14167 mgmt->frame_control |=
14168 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14169 }
14170 else
14171 {
14172 mgmt->frame_control |=
14173 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14174 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014175
14176#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014177 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014178 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014179 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014180 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014181 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014182 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014183 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014184
14185 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014186 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014187 }
14188 else
14189 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014190 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14191 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014192 kfree(mgmt);
14193 return NULL;
14194 }
14195#else
14196 freq = ieee80211_channel_to_frequency(chan_no);
14197#endif
14198 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014199 /*when the band is changed on the fly using the GUI, three things are done
14200 * 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)
14201 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14202 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14203 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14204 * and discards the channels correponding to previous band and calls back with zero bss results.
14205 * 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
14206 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14207 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14208 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14209 * So drop the bss and continue to next bss.
14210 */
14211 if(chan == NULL)
14212 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014213 hddLog(VOS_TRACE_LEVEL_ERROR,
14214 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14215 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014216 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014217 return NULL;
14218 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014219 /*To keep the rssi icon of the connected AP in the scan window
14220 *and the rssi icon of the wireless networks in sync
14221 * */
14222 if (( eConnectionState_Associated ==
14223 pAdapter->sessionCtx.station.conn_info.connState ) &&
14224 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14225 pAdapter->sessionCtx.station.conn_info.bssId,
14226 WNI_CFG_BSSID_LEN)) &&
14227 (pHddCtx->hdd_wlan_suspended == FALSE))
14228 {
14229 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14230 rssi = (pAdapter->rssi * 100);
14231 }
14232 else
14233 {
14234 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014236
Nirav Shah20ac06f2013-12-12 18:14:06 +053014237 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014238 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14239 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014240
Jeff Johnson295189b2012-06-20 16:38:30 -070014241 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14242 frame_len, rssi, GFP_KERNEL);
14243 kfree(mgmt);
14244 return bss_status;
14245}
14246
14247/*
14248 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14249 * This function is used to update the BSS data base of CFG8011
14250 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014251struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014252 tCsrRoamInfo *pRoamInfo
14253 )
14254{
14255 tCsrRoamConnectedProfile roamProfile;
14256 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14257 struct cfg80211_bss *bss = NULL;
14258
14259 ENTER();
14260
14261 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14262 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14263
14264 if (NULL != roamProfile.pBssDesc)
14265 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014266 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14267 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014268
14269 if (NULL == bss)
14270 {
14271 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14272 __func__);
14273 }
14274
14275 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14276 }
14277 else
14278 {
14279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14280 __func__);
14281 }
14282 return bss;
14283}
14284
14285/*
14286 * FUNCTION: wlan_hdd_cfg80211_update_bss
14287 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014288static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14289 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014290 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014291{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014292 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014293 tCsrScanResultInfo *pScanResult;
14294 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014295 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014296 tScanResultHandle pResult;
14297 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014298 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014299 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014300 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014301
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014302 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14303 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14304 NO_SESSION, pAdapter->sessionId));
14305
Wilson Yangf80a0542013-10-07 13:02:37 -070014306 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014307 ret = wlan_hdd_validate_context(pHddCtx);
14308 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014309 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014310 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014311 }
14312
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014313 if (pAdapter->request != NULL)
14314 {
14315 if ((pAdapter->request->n_ssids == 1)
14316 && (pAdapter->request->ssids != NULL)
14317 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14318 is_p2p_scan = true;
14319 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014320 /*
14321 * start getting scan results and populate cgf80211 BSS database
14322 */
14323 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14324
14325 /* no scan results */
14326 if (NULL == pResult)
14327 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014328 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14329 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014330 wlan_hdd_get_frame_logs(pAdapter,
14331 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014332 return status;
14333 }
14334
14335 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14336
14337 while (pScanResult)
14338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014339 /*
14340 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14341 * entry already exists in bss data base of cfg80211 for that
14342 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14343 * bss entry instead of cfg80211_inform_bss, But this call expects
14344 * mgmt packet as input. As of now there is no possibility to get
14345 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 * ieee80211_mgmt(probe response) and passing to c
14347 * fg80211_inform_bss_frame.
14348 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014349 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14350 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14351 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014352 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14353 continue; //Skip the non p2p bss entries
14354 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014355 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14356 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014357
Jeff Johnson295189b2012-06-20 16:38:30 -070014358
14359 if (NULL == bss_status)
14360 {
14361 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014362 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014363 }
14364 else
14365 {
Yue Maf49ba872013-08-19 12:04:25 -070014366 cfg80211_put_bss(
14367#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14368 wiphy,
14369#endif
14370 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014371 }
14372
14373 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14374 }
14375
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014376 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014377 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014378 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014379}
14380
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014381void
14382hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14383{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014384 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014385 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014386} /****** end hddPrintMacAddr() ******/
14387
14388void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014389hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014390{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014391 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014392 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014393 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14394 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14395 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014396} /****** end hddPrintPmkId() ******/
14397
14398//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14399//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14400
14401//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14402//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14403
14404#define dump_bssid(bssid) \
14405 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014406 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14407 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014408 }
14409
14410#define dump_pmkid(pMac, pmkid) \
14411 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014412 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14413 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014414 }
14415
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014416#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014417/*
14418 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14419 * This function is used to notify the supplicant of a new PMKSA candidate.
14420 */
14421int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014422 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014423 int index, bool preauth )
14424{
Jeff Johnsone7245742012-09-05 17:12:55 -070014425#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014426 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014427 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014428
14429 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014430 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014431
14432 if( NULL == pRoamInfo )
14433 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014434 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014435 return -EINVAL;
14436 }
14437
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014438 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14439 {
14440 dump_bssid(pRoamInfo->bssid);
14441 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014442 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014443 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014444#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014445 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014446}
14447#endif //FEATURE_WLAN_LFR
14448
Yue Maef608272013-04-08 23:09:17 -070014449#ifdef FEATURE_WLAN_LFR_METRICS
14450/*
14451 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14452 * 802.11r/LFR metrics reporting function to report preauth initiation
14453 *
14454 */
14455#define MAX_LFR_METRICS_EVENT_LENGTH 100
14456VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14457 tCsrRoamInfo *pRoamInfo)
14458{
14459 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14460 union iwreq_data wrqu;
14461
14462 ENTER();
14463
14464 if (NULL == pAdapter)
14465 {
14466 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14467 return VOS_STATUS_E_FAILURE;
14468 }
14469
14470 /* create the event */
14471 memset(&wrqu, 0, sizeof(wrqu));
14472 memset(metrics_notification, 0, sizeof(metrics_notification));
14473
14474 wrqu.data.pointer = metrics_notification;
14475 wrqu.data.length = scnprintf(metrics_notification,
14476 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14477 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14478
14479 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14480
14481 EXIT();
14482
14483 return VOS_STATUS_SUCCESS;
14484}
14485
14486/*
14487 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14488 * 802.11r/LFR metrics reporting function to report preauth completion
14489 * or failure
14490 */
14491VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14492 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14493{
14494 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14495 union iwreq_data wrqu;
14496
14497 ENTER();
14498
14499 if (NULL == pAdapter)
14500 {
14501 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14502 return VOS_STATUS_E_FAILURE;
14503 }
14504
14505 /* create the event */
14506 memset(&wrqu, 0, sizeof(wrqu));
14507 memset(metrics_notification, 0, sizeof(metrics_notification));
14508
14509 scnprintf(metrics_notification, sizeof(metrics_notification),
14510 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14511 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14512
14513 if (1 == preauth_status)
14514 strncat(metrics_notification, " TRUE", 5);
14515 else
14516 strncat(metrics_notification, " FALSE", 6);
14517
14518 wrqu.data.pointer = metrics_notification;
14519 wrqu.data.length = strlen(metrics_notification);
14520
14521 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14522
14523 EXIT();
14524
14525 return VOS_STATUS_SUCCESS;
14526}
14527
14528/*
14529 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14530 * 802.11r/LFR metrics reporting function to report handover initiation
14531 *
14532 */
14533VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14534 tCsrRoamInfo *pRoamInfo)
14535{
14536 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14537 union iwreq_data wrqu;
14538
14539 ENTER();
14540
14541 if (NULL == pAdapter)
14542 {
14543 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14544 return VOS_STATUS_E_FAILURE;
14545 }
14546
14547 /* create the event */
14548 memset(&wrqu, 0, sizeof(wrqu));
14549 memset(metrics_notification, 0, sizeof(metrics_notification));
14550
14551 wrqu.data.pointer = metrics_notification;
14552 wrqu.data.length = scnprintf(metrics_notification,
14553 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14554 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14555
14556 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14557
14558 EXIT();
14559
14560 return VOS_STATUS_SUCCESS;
14561}
14562#endif
14563
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014564
14565/**
14566 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14567 * @scan_req: scan request to be checked
14568 *
14569 * Return: true or false
14570 */
14571#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14572static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14573 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014574 *scan_req, hdd_context_t
14575 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014576{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014577 if (!scan_req || !scan_req->wiphy ||
14578 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014579 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14580 return false;
14581 }
14582 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14583 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14584 return false;
14585 }
14586 return true;
14587}
14588#else
14589static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14590 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014591 *scan_req, hdd_context_t
14592 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014593{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014594 if (!scan_req || !scan_req->wiphy ||
14595 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014596 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14597 return false;
14598 }
14599 return true;
14600}
14601#endif
14602
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14604/**
14605 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14606 * @adapter: Pointer to the adapter
14607 * @req : Scan request
14608 * @aborted : true scan aborted false scan success
14609 *
14610 * This function notifies scan done to cfg80211
14611 *
14612 * Return: none
14613 */
14614static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14615 struct cfg80211_scan_request *req,
14616 bool aborted)
14617{
14618 struct cfg80211_scan_info info = {
14619 .aborted = aborted
14620 };
14621
14622 if (adapter->dev->flags & IFF_UP)
14623 cfg80211_scan_done(req, &info);
14624 else
14625 hddLog(LOGW,
14626 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14627}
14628#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14629/**
14630 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14631 * @adapter: Pointer to the adapter
14632 * @req : Scan request
14633 * @aborted : true scan aborted false scan success
14634 *
14635 * This function notifies scan done to cfg80211
14636 *
14637 * Return: none
14638 */
14639static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14640 struct cfg80211_scan_request *req,
14641 bool aborted)
14642{
14643 if (adapter->dev->flags & IFF_UP)
14644 cfg80211_scan_done(req, aborted);
14645 else
14646 hddLog(LOGW,
14647 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14648}
14649#else
14650/**
14651 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14652 * @adapter: Pointer to the adapter
14653 * @req : Scan request
14654 * @aborted : true scan aborted false scan success
14655 *
14656 * This function notifies scan done to cfg80211
14657 *
14658 * Return: none
14659 */
14660static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14661 struct cfg80211_scan_request *req,
14662 bool aborted)
14663{
14664 cfg80211_scan_done(req, aborted);
14665}
14666#endif
14667
Mukul Sharmab392b642017-08-17 17:45:29 +053014668#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014669/*
14670 * FUNCTION: hdd_cfg80211_scan_done_callback
14671 * scanning callback function, called after finishing scan
14672 *
14673 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014674static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014675 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14676{
14677 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014678 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014680 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014681 struct cfg80211_scan_request *req = NULL;
14682 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014683 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014684 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014685 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014686
14687 ENTER();
14688
c_manjee1b4ab9a2016-10-26 11:36:55 +053014689 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14690 !pAdapter->dev) {
14691 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14692 return 0;
14693 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014694 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014695 if (NULL == pHddCtx) {
14696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014697 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014698 }
14699
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014701 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014702 {
14703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014704 }
14705#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014706 pScanInfo = &pHddCtx->scan_info;
14707
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014709 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014710 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 __func__, halHandle, pContext, (int) scanId, (int) status);
14712
Kiet Lamac06e2c2013-10-23 16:25:07 +053014713 pScanInfo->mScanPendingCounter = 0;
14714
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014716 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 &pScanInfo->scan_req_completion_event,
14718 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014719 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014721 hddLog(VOS_TRACE_LEVEL_ERROR,
14722 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014723 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014724 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 }
14726
Yue Maef608272013-04-08 23:09:17 -070014727 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014728 {
14729 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014730 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014731 }
14732
14733 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014734 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 {
14736 hddLog(VOS_TRACE_LEVEL_INFO,
14737 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014738 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014739 (int) scanId);
14740 }
14741
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014742#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014743 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014744#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014745 {
14746 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14747 pAdapter);
14748 if (0 > ret)
14749 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014750 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014751
Jeff Johnson295189b2012-06-20 16:38:30 -070014752 /* If any client wait scan result through WEXT
14753 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014754 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014755 {
14756 /* The other scan request waiting for current scan finish
14757 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014758 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014759 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014760 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 }
14762 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014763 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 {
14765 struct net_device *dev = pAdapter->dev;
14766 union iwreq_data wrqu;
14767 int we_event;
14768 char *msg;
14769
14770 memset(&wrqu, '\0', sizeof(wrqu));
14771 we_event = SIOCGIWSCAN;
14772 msg = NULL;
14773 wireless_send_event(dev, we_event, &wrqu, msg);
14774 }
14775 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014776 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014777
14778 /* Get the Scan Req */
14779 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014780 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014781
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014782 /* Scan is no longer pending */
14783 pScanInfo->mScanPending = VOS_FALSE;
14784
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014785 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014786 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014789 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014790#endif
14791
14792 if (pAdapter->dev) {
14793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14794 pAdapter->dev->name);
14795 }
mukul sharmae7041822015-12-03 15:09:21 +053014796 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014797 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014798 }
14799
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014800 /* last_scan_timestamp is used to decide if new scan
14801 * is needed or not on station interface. If last station
14802 * scan time and new station scan time is less then
14803 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014804 * Also only last_scan_timestamp is updated here last_scan_channellist
14805 * is updated on receiving scan request itself to make sure kernel
14806 * allocated scan request(scan_req) object is not dereferenced here,
14807 * because interface down, where kernel frees scan_req, may happen any
14808 * time while driver is processing scan_done_callback. So it's better
14809 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014810 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014811 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14812 if (status == eCSR_SCAN_SUCCESS)
14813 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14814 else {
14815 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14816 sizeof(pHddCtx->scan_info.last_scan_channelList));
14817 pHddCtx->scan_info.last_scan_numChannels = 0;
14818 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014819 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014820 }
14821
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014822 /*
14823 * cfg80211_scan_done informing NL80211 about completion
14824 * of scanning
14825 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014826 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14827 {
14828 aborted = true;
14829 }
mukul sharmae7041822015-12-03 15:09:21 +053014830
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014832 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14833 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014834#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014835 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014836
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014837 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014838
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014839allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014840 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14841 ) && (pHddCtx->spoofMacAddr.isEnabled
14842 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014843 /* Generate new random mac addr for next scan */
14844 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014845
14846 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14847 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014848 }
14849
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014850 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014851 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014852
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014853 /* Acquire wakelock to handle the case where APP's tries to suspend
14854 * immediatly after the driver gets connect request(i.e after scan)
14855 * from supplicant, this result in app's is suspending and not able
14856 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014857 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014858
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014860 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014861#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014862#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014863 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014864#endif
14865
Jeff Johnson295189b2012-06-20 16:38:30 -070014866 EXIT();
14867 return 0;
14868}
14869
14870/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014871 * FUNCTION: hdd_isConnectionInProgress
14872 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014873 *
14874 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014875v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14876 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014877{
14878 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14879 hdd_station_ctx_t *pHddStaCtx = NULL;
14880 hdd_adapter_t *pAdapter = NULL;
14881 VOS_STATUS status = 0;
14882 v_U8_t staId = 0;
14883 v_U8_t *staMac = NULL;
14884
14885 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14886
14887 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14888 {
14889 pAdapter = pAdapterNode->pAdapter;
14890
14891 if( pAdapter )
14892 {
14893 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014894 "%s: Adapter with device mode %s (%d) exists",
14895 __func__, hdd_device_modetoString(pAdapter->device_mode),
14896 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014897 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014898 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14899 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14900 (eConnectionState_Connecting ==
14901 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14902 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014903 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014904 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014905 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014906 if (session_id && reason)
14907 {
14908 *session_id = pAdapter->sessionId;
14909 *reason = eHDD_CONNECTION_IN_PROGRESS;
14910 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014911 return VOS_TRUE;
14912 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014913 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014914 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014915 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014916 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014917 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014918 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014919 if (session_id && reason)
14920 {
14921 *session_id = pAdapter->sessionId;
14922 *reason = eHDD_REASSOC_IN_PROGRESS;
14923 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014924 return VOS_TRUE;
14925 }
14926 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014927 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14928 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014929 {
14930 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14931 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014932 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014933 {
14934 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014935 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014936 "%s: client " MAC_ADDRESS_STR
14937 " is in the middle of WPS/EAPOL exchange.", __func__,
14938 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014939 if (session_id && reason)
14940 {
14941 *session_id = pAdapter->sessionId;
14942 *reason = eHDD_EAPOL_IN_PROGRESS;
14943 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014944 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014945 }
14946 }
14947 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14948 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14949 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014950 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14951 ptSapContext pSapCtx = NULL;
14952 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14953 if(pSapCtx == NULL){
14954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14955 FL("psapCtx is NULL"));
14956 return VOS_FALSE;
14957 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014958 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14959 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014960 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14961 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014962 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014963 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014964
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014965 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014966 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14967 "middle of WPS/EAPOL exchange.", __func__,
14968 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014969 if (session_id && reason)
14970 {
14971 *session_id = pAdapter->sessionId;
14972 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14973 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014974 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014975 }
14976 }
14977 }
14978 }
14979 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14980 pAdapterNode = pNext;
14981 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014982 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014983}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014984
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014985/**
14986 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14987 * to the Scan request
14988 * @scanRequest: Pointer to the csr scan request
14989 * @request: Pointer to the scan request from supplicant
14990 *
14991 * Return: None
14992 */
14993#ifdef CFG80211_SCAN_BSSID
14994static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14995 struct cfg80211_scan_request *request)
14996{
14997 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14998}
14999#else
15000static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15001 struct cfg80211_scan_request *request)
15002{
15003}
15004#endif
15005
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015006/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015007 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015008 * this scan respond to scan trigger and update cfg80211 scan database
15009 * later, scan dump command can be used to recieve scan results
15010 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015011int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015012#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15013 struct net_device *dev,
15014#endif
15015 struct cfg80211_scan_request *request)
15016{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015017 hdd_adapter_t *pAdapter = NULL;
15018 hdd_context_t *pHddCtx = NULL;
15019 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015020 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015021 tCsrScanRequest scanRequest;
15022 tANI_U8 *channelList = NULL, i;
15023 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015024 int status;
15025 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015026 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015027 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015028 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015029 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015030 v_U8_t curr_session_id;
15031 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015032
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015033#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15034 struct net_device *dev = NULL;
15035 if (NULL == request)
15036 {
15037 hddLog(VOS_TRACE_LEVEL_ERROR,
15038 "%s: scan req param null", __func__);
15039 return -EINVAL;
15040 }
15041 dev = request->wdev->netdev;
15042#endif
15043
15044 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15045 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15046 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15047
Jeff Johnson295189b2012-06-20 16:38:30 -070015048 ENTER();
15049
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15051 __func__, hdd_device_modetoString(pAdapter->device_mode),
15052 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015053
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015054 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015055 if (0 != status)
15056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015057 return status;
15058 }
15059
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015060 if (NULL == pwextBuf)
15061 {
15062 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15063 __func__);
15064 return -EIO;
15065 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015066 cfg_param = pHddCtx->cfg_ini;
15067 pScanInfo = &pHddCtx->scan_info;
15068
Jeff Johnson295189b2012-06-20 16:38:30 -070015069#ifdef WLAN_BTAMP_FEATURE
15070 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015071 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015072 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015073 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015074 "%s: No scanning when AMP is on", __func__);
15075 return -EOPNOTSUPP;
15076 }
15077#endif
15078 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015079 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015080 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015081 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015082 "%s: Not scanning on device_mode = %s (%d)",
15083 __func__, hdd_device_modetoString(pAdapter->device_mode),
15084 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015085 return -EOPNOTSUPP;
15086 }
15087
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015088 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15089 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15090 return -EOPNOTSUPP;
15091 }
15092
Jeff Johnson295189b2012-06-20 16:38:30 -070015093 if (TRUE == pScanInfo->mScanPending)
15094 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015095 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15096 {
15097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15098 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015099 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015100 }
15101
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015102 // Don't allow scan if PNO scan is going on.
15103 if (pHddCtx->isPnoEnable)
15104 {
15105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15106 FL("pno scan in progress"));
15107 return -EBUSY;
15108 }
15109
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015110 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015111 //Channel and action frame is pending
15112 //Otherwise Cancel Remain On Channel and allow Scan
15113 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015114 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015115 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015117 return -EBUSY;
15118 }
15119
Jeff Johnson295189b2012-06-20 16:38:30 -070015120 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15121 {
15122 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015123 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015124 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015125 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015126 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15127 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015128 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015129 "%s: MAX TM Level Scan not allowed", __func__);
15130 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015131 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015132 }
15133 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15134
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015135 /* Check if scan is allowed at this point of time.
15136 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015137 if (TRUE == pHddCtx->btCoexModeSet)
15138 {
15139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15140 FL("BTCoex Mode operation in progress"));
15141 return -EBUSY;
15142 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015143 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015144 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015145
15146 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15147 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15148 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015149 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15150 pHddCtx->last_scan_reject_reason != curr_reason ||
15151 !pHddCtx->last_scan_reject_timestamp)
15152 {
15153 pHddCtx->last_scan_reject_session_id = curr_session_id;
15154 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015155 pHddCtx->last_scan_reject_timestamp =
15156 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015157 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015158 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015159 else
15160 {
15161 pHddCtx->scan_reject_cnt++;
15162
Abhishek Singhe4b12562017-06-20 16:53:39 +053015163 if ((pHddCtx->scan_reject_cnt >=
15164 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015165 vos_system_time_after(jiffies_to_msecs(jiffies),
15166 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015167 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015168 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15169 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15170 vos_system_time_after(jiffies_to_msecs(jiffies),
15171 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015172 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015173 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015174 if (pHddCtx->cfg_ini->enableFatalEvent)
15175 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15176 WLAN_LOG_INDICATOR_HOST_DRIVER,
15177 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15178 FALSE, FALSE);
15179 else
15180 {
15181 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015182 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015183 }
15184 }
15185 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015186 return -EBUSY;
15187 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015188 pHddCtx->last_scan_reject_timestamp = 0;
15189 pHddCtx->last_scan_reject_session_id = 0xFF;
15190 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015191 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015192
Jeff Johnson295189b2012-06-20 16:38:30 -070015193 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15194
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015195 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15196 * Becasue of this, driver is assuming that this is not wildcard scan and so
15197 * is not aging out the scan results.
15198 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015199 if ((request->ssids) && (request->n_ssids == 1) &&
15200 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015201 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015203
15204 if ((request->ssids) && (0 < request->n_ssids))
15205 {
15206 tCsrSSIDInfo *SsidInfo;
15207 int j;
15208 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15209 /* Allocate num_ssid tCsrSSIDInfo structure */
15210 SsidInfo = scanRequest.SSIDs.SSIDList =
15211 ( tCsrSSIDInfo *)vos_mem_malloc(
15212 request->n_ssids*sizeof(tCsrSSIDInfo));
15213
15214 if(NULL == scanRequest.SSIDs.SSIDList)
15215 {
15216 hddLog(VOS_TRACE_LEVEL_ERROR,
15217 "%s: memory alloc failed SSIDInfo buffer", __func__);
15218 return -ENOMEM;
15219 }
15220
15221 /* copy all the ssid's and their length */
15222 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15223 {
15224 /* get the ssid length */
15225 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15226 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15227 SsidInfo->SSID.length);
15228 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15229 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15230 j, SsidInfo->SSID.ssId);
15231 }
15232 /* set the scan type to active */
15233 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15234 }
15235 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015236 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015237 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15238 TRACE_CODE_HDD_CFG80211_SCAN,
15239 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015240 /* set the scan type to active */
15241 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015242 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015243 else
15244 {
15245 /*Set the scan type to default type, in this case it is ACTIVE*/
15246 scanRequest.scanType = pScanInfo->scan_mode;
15247 }
15248 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15249 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015250
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015251 csr_scan_request_assign_bssid(&scanRequest, request);
15252
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 /* set BSSType to default type */
15254 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15255
15256 /*TODO: scan the requested channels only*/
15257
15258 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015259 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015261 hddLog(VOS_TRACE_LEVEL_WARN,
15262 "No of Scan Channels exceeded limit: %d", request->n_channels);
15263 request->n_channels = MAX_CHANNEL;
15264 }
15265
15266 hddLog(VOS_TRACE_LEVEL_INFO,
15267 "No of Scan Channels: %d", request->n_channels);
15268
15269
15270 if( request->n_channels )
15271 {
15272 char chList [(request->n_channels*5)+1];
15273 int len;
15274 channelList = vos_mem_malloc( request->n_channels );
15275 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015276 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015277 hddLog(VOS_TRACE_LEVEL_ERROR,
15278 "%s: memory alloc failed channelList", __func__);
15279 status = -ENOMEM;
15280 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015281 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015282
15283 for( i = 0, len = 0; i < request->n_channels ; i++ )
15284 {
15285 channelList[i] = request->channels[i]->hw_value;
15286 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15287 }
15288
Nirav Shah20ac06f2013-12-12 18:14:06 +053015289 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015290 "Channel-List: %s ", chList);
15291 }
c_hpothu53512302014-04-15 18:49:53 +053015292
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015293 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15294 scanRequest.ChannelInfo.ChannelList = channelList;
15295
15296 /* set requestType to full scan */
15297 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15298
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015299 /* if there is back to back scan happening in driver with in
15300 * nDeferScanTimeInterval interval driver should defer new scan request
15301 * and should provide last cached scan results instead of new channel list.
15302 * This rule is not applicable if scan is p2p scan.
15303 * This condition will work only in case when last request no of channels
15304 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015305 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015306 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015307 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015308
Sushant Kaushik86592172015-04-27 16:35:03 +053015309 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15310 /* if wps ie is NULL , then only defer scan */
15311 if ( pWpsIe == NULL &&
15312 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015313 {
15314 if ( pScanInfo->last_scan_timestamp !=0 &&
15315 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15316 {
15317 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15318 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15319 vos_mem_compare(pScanInfo->last_scan_channelList,
15320 channelList, pScanInfo->last_scan_numChannels))
15321 {
15322 hddLog(VOS_TRACE_LEVEL_WARN,
15323 " New and old station scan time differ is less then %u",
15324 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15325
15326 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015327 pAdapter);
15328
Agarwal Ashish57e84372014-12-05 18:26:53 +053015329 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015330 "Return old cached scan as all channels and no of channels are same");
15331
Agarwal Ashish57e84372014-12-05 18:26:53 +053015332 if (0 > ret)
15333 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015334
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015335 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015336
15337 status = eHAL_STATUS_SUCCESS;
15338 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015339 }
15340 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015341 }
15342
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015343 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15344 * search (Flush on both full scan and social scan but not on single
15345 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15346 */
15347
15348 /* Supplicant does single channel scan after 8-way handshake
15349 * and in that case driver shoudnt flush scan results. If
15350 * driver flushes the scan results here and unfortunately if
15351 * the AP doesnt respond to our probe req then association
15352 * fails which is not desired
15353 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015354 if ((request->n_ssids == 1)
15355 && (request->ssids != NULL)
15356 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15357 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015358
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015359 if( is_p2p_scan ||
15360 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015361 {
15362 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15363 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15364 pAdapter->sessionId );
15365 }
15366
15367 if( request->ie_len )
15368 {
15369 /* save this for future association (join requires this) */
15370 /*TODO: Array needs to be converted to dynamic allocation,
15371 * as multiple ie.s can be sent in cfg80211_scan_request structure
15372 * CR 597966
15373 */
15374 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15375 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15376 pScanInfo->scanAddIE.length = request->ie_len;
15377
15378 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15379 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15380 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015381 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015382 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015383 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015384 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15385 memcpy( pwextBuf->roamProfile.addIEScan,
15386 request->ie, request->ie_len);
15387 }
15388 else
15389 {
15390 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15391 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015392 }
15393
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015394 }
15395 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15396 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15397
15398 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15399 request->ie_len);
15400 if (pP2pIe != NULL)
15401 {
15402#ifdef WLAN_FEATURE_P2P_DEBUG
15403 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15404 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15405 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015406 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015407 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15408 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15409 "Go nego completed to Connection is started");
15410 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15411 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015412 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015413 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15414 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015415 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015416 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15417 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15418 "Disconnected state to Connection is started");
15419 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15420 "for 4way Handshake");
15421 }
15422#endif
15423
15424 /* no_cck will be set during p2p find to disable 11b rates */
15425 if(TRUE == request->no_cck)
15426 {
15427 hddLog(VOS_TRACE_LEVEL_INFO,
15428 "%s: This is a P2P Search", __func__);
15429 scanRequest.p2pSearch = 1;
15430
15431 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015432 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015433 /* set requestType to P2P Discovery */
15434 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15435 }
15436
15437 /*
15438 Skip Dfs Channel in case of P2P Search
15439 if it is set in ini file
15440 */
15441 if(cfg_param->skipDfsChnlInP2pSearch)
15442 {
15443 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015444 }
15445 else
15446 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015447 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015448 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015449
Agarwal Ashish4f616132013-12-30 23:32:50 +053015450 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015451 }
15452 }
15453
15454 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15455
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015456#ifdef FEATURE_WLAN_TDLS
15457 /* if tdls disagree scan right now, return immediately.
15458 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15459 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15460 */
15461 status = wlan_hdd_tdls_scan_callback (pAdapter,
15462 wiphy,
15463#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15464 dev,
15465#endif
15466 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015467 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015468 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015469 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015470 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15471 "scan rejected %d", __func__, status);
15472 else
15473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15474 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015475 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015476 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015477 }
15478#endif
15479
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015480 /* acquire the wakelock to avoid the apps suspend during the scan. To
15481 * address the following issues.
15482 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15483 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15484 * for long time, this result in apps running at full power for long time.
15485 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15486 * be stuck in full power because of resume BMPS
15487 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015488 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015489
Nirav Shah20ac06f2013-12-12 18:14:06 +053015490 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15491 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015492 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15493 scanRequest.requestType, scanRequest.scanType,
15494 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015495 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15496
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015497 if (pHddCtx->spoofMacAddr.isEnabled &&
15498 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015499 {
15500 hddLog(VOS_TRACE_LEVEL_INFO,
15501 "%s: MAC Spoofing enabled for current scan", __func__);
15502 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15503 * to fill TxBds for probe request during current scan
15504 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015505 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015506 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015507
15508 if(status != VOS_STATUS_SUCCESS)
15509 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015510 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015511 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015512#ifdef FEATURE_WLAN_TDLS
15513 wlan_hdd_tdls_scan_done_callback(pAdapter);
15514#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015515 goto free_mem;
15516 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015517 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015518 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015519 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015520 pAdapter->sessionId, &scanRequest, &scanId,
15521 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015522
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 if (eHAL_STATUS_SUCCESS != status)
15524 {
15525 hddLog(VOS_TRACE_LEVEL_ERROR,
15526 "%s: sme_ScanRequest returned error %d", __func__, status);
15527 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015528 if(eHAL_STATUS_RESOURCES == status)
15529 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15531 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015532 status = -EBUSY;
15533 } else {
15534 status = -EIO;
15535 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015536 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015537
15538#ifdef FEATURE_WLAN_TDLS
15539 wlan_hdd_tdls_scan_done_callback(pAdapter);
15540#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 goto free_mem;
15542 }
15543
15544 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015545 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015546 pAdapter->request = request;
15547 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015548 pScanInfo->no_cck = request->no_cck;
15549 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15550 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15551 pHddCtx->scan_info.last_scan_channelList[i] =
15552 request->channels[i]->hw_value;
15553 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015554
15555 complete(&pScanInfo->scan_req_completion_event);
15556
15557free_mem:
15558 if( scanRequest.SSIDs.SSIDList )
15559 {
15560 vos_mem_free(scanRequest.SSIDs.SSIDList);
15561 }
15562
15563 if( channelList )
15564 vos_mem_free( channelList );
15565
15566 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015567 return status;
15568}
15569
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015570int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15571#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15572 struct net_device *dev,
15573#endif
15574 struct cfg80211_scan_request *request)
15575{
15576 int ret;
15577
15578 vos_ssr_protect(__func__);
15579 ret = __wlan_hdd_cfg80211_scan(wiphy,
15580#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15581 dev,
15582#endif
15583 request);
15584 vos_ssr_unprotect(__func__);
15585
15586 return ret;
15587}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015588
15589void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15590{
15591 v_U8_t iniDot11Mode =
15592 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15593 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15594
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015595 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15596 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015597 switch ( iniDot11Mode )
15598 {
15599 case eHDD_DOT11_MODE_AUTO:
15600 case eHDD_DOT11_MODE_11ac:
15601 case eHDD_DOT11_MODE_11ac_ONLY:
15602#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015603 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15604 sme_IsFeatureSupportedByFW(DOT11AC) )
15605 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15606 else
15607 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015608#else
15609 hddDot11Mode = eHDD_DOT11_MODE_11n;
15610#endif
15611 break;
15612 case eHDD_DOT11_MODE_11n:
15613 case eHDD_DOT11_MODE_11n_ONLY:
15614 hddDot11Mode = eHDD_DOT11_MODE_11n;
15615 break;
15616 default:
15617 hddDot11Mode = iniDot11Mode;
15618 break;
15619 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015620#ifdef WLAN_FEATURE_AP_HT40_24G
15621 if (operationChannel > SIR_11B_CHANNEL_END)
15622#endif
15623 {
15624 /* This call decides required channel bonding mode */
15625 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015626 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015627 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015628 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015629}
15630
Jeff Johnson295189b2012-06-20 16:38:30 -070015631/*
15632 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015633 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015634 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015635int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015636 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15637 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015638{
15639 int status = 0;
15640 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015641 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015642 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015643 v_U32_t roamId;
15644 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 eCsrAuthType RSNAuthType;
15646
15647 ENTER();
15648
15649 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015650 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015651 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015652
15653 status = wlan_hdd_validate_context(pHddCtx);
15654 if (status)
15655 {
Yue Mae36e3552014-03-05 17:06:20 -080015656 return status;
15657 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015658
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15660 {
15661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15662 return -EINVAL;
15663 }
15664
Nitesh Shah9b066282017-06-06 18:05:52 +053015665 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15666
Jeff Johnson295189b2012-06-20 16:38:30 -070015667 pRoamProfile = &pWextState->roamProfile;
15668
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015669 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015670 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015671 hdd_station_ctx_t *pHddStaCtx;
15672 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015673 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015674
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015675 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15676
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015677 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15679 {
15680 /*QoS not enabled in cfg file*/
15681 pRoamProfile->uapsd_mask = 0;
15682 }
15683 else
15684 {
15685 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015686 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015687 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15688 }
15689
15690 pRoamProfile->SSIDs.numOfSSIDs = 1;
15691 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15692 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015693 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015694 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15695 ssid, ssid_len);
15696
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015697 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15698 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15699
Jeff Johnson295189b2012-06-20 16:38:30 -070015700 if (bssid)
15701 {
15702 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015703 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015704 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015705 /* Save BSSID in seperate variable as well, as RoamProfile
15706 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015707 case of join failure we should send valid BSSID to supplicant
15708 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015709 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015710 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015711
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015713 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015714 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015715 /* Store bssid_hint to use in the scan filter. */
15716 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15717 WNI_CFG_BSSID_LEN);
15718 /*
15719 * Save BSSID in seperate variable as well, as RoamProfile
15720 * BSSID is getting zeroed out in the association process. And in
15721 * case of join failure we should send valid BSSID to supplicant
15722 */
15723 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15724 WNI_CFG_BSSID_LEN);
15725 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15726 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015728
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015729
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015730 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15731 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015732 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15733 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015734 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015735 /*set gen ie*/
15736 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15737 /*set auth*/
15738 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15739 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015740#ifdef FEATURE_WLAN_WAPI
15741 if (pAdapter->wapi_info.nWapiMode)
15742 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015743 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015744 switch (pAdapter->wapi_info.wapiAuthMode)
15745 {
15746 case WAPI_AUTH_MODE_PSK:
15747 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015748 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015749 pAdapter->wapi_info.wapiAuthMode);
15750 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15751 break;
15752 }
15753 case WAPI_AUTH_MODE_CERT:
15754 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015755 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015756 pAdapter->wapi_info.wapiAuthMode);
15757 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15758 break;
15759 }
15760 } // End of switch
15761 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15762 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15763 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015764 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015765 pRoamProfile->AuthType.numEntries = 1;
15766 pRoamProfile->EncryptionType.numEntries = 1;
15767 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15768 pRoamProfile->mcEncryptionType.numEntries = 1;
15769 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15770 }
15771 }
15772#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015773#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015774 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015775 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15776 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15777 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015778 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15779 sizeof (tSirGtkOffloadParams));
15780 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015781 }
15782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015783 pRoamProfile->csrPersona = pAdapter->device_mode;
15784
Jeff Johnson32d95a32012-09-10 13:15:23 -070015785 if( operatingChannel )
15786 {
15787 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15788 pRoamProfile->ChannelInfo.numOfChannels = 1;
15789 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015790 else
15791 {
15792 pRoamProfile->ChannelInfo.ChannelList = NULL;
15793 pRoamProfile->ChannelInfo.numOfChannels = 0;
15794 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015795 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15796 {
15797 hdd_select_cbmode(pAdapter,operatingChannel);
15798 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015799
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015800 /*
15801 * Change conn_state to connecting before sme_RoamConnect(),
15802 * because sme_RoamConnect() has a direct path to call
15803 * hdd_smeRoamCallback(), which will change the conn_state
15804 * If direct path, conn_state will be accordingly changed
15805 * to NotConnected or Associated by either
15806 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15807 * in sme_RoamCallback()
15808 * if sme_RomConnect is to be queued,
15809 * Connecting state will remain until it is completed.
15810 * If connection state is not changed,
15811 * connection state will remain in eConnectionState_NotConnected state.
15812 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15813 * if conn state is eConnectionState_NotConnected.
15814 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15815 * informed of connect result indication which is an issue.
15816 */
15817
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015818 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15819 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015820 {
15821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015822 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015823 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15824 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015825 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
15826 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015827 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015828
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015829 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015830 pAdapter->sessionId, pRoamProfile, &roamId);
15831
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015832 if ((eHAL_STATUS_SUCCESS != status) &&
15833 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15834 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015835
15836 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015837 hddLog(VOS_TRACE_LEVEL_ERROR,
15838 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15839 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015840 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015841 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015842 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015843 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015844
15845 pRoamProfile->ChannelInfo.ChannelList = NULL;
15846 pRoamProfile->ChannelInfo.numOfChannels = 0;
15847
Jeff Johnson295189b2012-06-20 16:38:30 -070015848 }
15849 else
15850 {
15851 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15852 return -EINVAL;
15853 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015854 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015855 return status;
15856}
15857
15858/*
15859 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15860 * This function is used to set the authentication type (OPEN/SHARED).
15861 *
15862 */
15863static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15864 enum nl80211_auth_type auth_type)
15865{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015866 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015867 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15868
15869 ENTER();
15870
15871 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015872 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015873 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015874 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015875 hddLog(VOS_TRACE_LEVEL_INFO,
15876 "%s: set authentication type to AUTOSWITCH", __func__);
15877 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15878 break;
15879
15880 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015881#ifdef WLAN_FEATURE_VOWIFI_11R
15882 case NL80211_AUTHTYPE_FT:
15883#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015884 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015885 "%s: set authentication type to OPEN", __func__);
15886 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15887 break;
15888
15889 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015890 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015891 "%s: set authentication type to SHARED", __func__);
15892 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15893 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015894#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015896 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015897 "%s: set authentication type to CCKM WPA", __func__);
15898 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15899 break;
15900#endif
15901
15902
15903 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015904 hddLog(VOS_TRACE_LEVEL_ERROR,
15905 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 auth_type);
15907 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15908 return -EINVAL;
15909 }
15910
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015911 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015912 pHddStaCtx->conn_info.authType;
15913 return 0;
15914}
15915
15916/*
15917 * FUNCTION: wlan_hdd_set_akm_suite
15918 * This function is used to set the key mgmt type(PSK/8021x).
15919 *
15920 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015921static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015922 u32 key_mgmt
15923 )
15924{
15925 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15926 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015927 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015928#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015929#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015930#endif
15931#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015932#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015933#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015934 /*set key mgmt type*/
15935 switch(key_mgmt)
15936 {
15937 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015938 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015939#ifdef WLAN_FEATURE_VOWIFI_11R
15940 case WLAN_AKM_SUITE_FT_PSK:
15941#endif
15942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015943 __func__);
15944 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15945 break;
15946
15947 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015948 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015949#ifdef WLAN_FEATURE_VOWIFI_11R
15950 case WLAN_AKM_SUITE_FT_8021X:
15951#endif
15952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015953 __func__);
15954 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15955 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015956#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015957#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15958#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15959 case WLAN_AKM_SUITE_CCKM:
15960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15961 __func__);
15962 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15963 break;
15964#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015965#ifndef WLAN_AKM_SUITE_OSEN
15966#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15967 case WLAN_AKM_SUITE_OSEN:
15968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15969 __func__);
15970 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15971 break;
15972#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015973
15974 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015976 __func__, key_mgmt);
15977 return -EINVAL;
15978
15979 }
15980 return 0;
15981}
15982
15983/*
15984 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015985 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015986 * (NONE/WEP40/WEP104/TKIP/CCMP).
15987 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015988static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15989 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 bool ucast
15991 )
15992{
15993 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015994 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015995 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15996
15997 ENTER();
15998
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015999 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016001 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 __func__, cipher);
16003 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16004 }
16005 else
16006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016007
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016009 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016010 {
16011 case IW_AUTH_CIPHER_NONE:
16012 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16013 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016014
Jeff Johnson295189b2012-06-20 16:38:30 -070016015 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016016 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016017 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016018
Jeff Johnson295189b2012-06-20 16:38:30 -070016019 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016020 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016021 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016022
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 case WLAN_CIPHER_SUITE_TKIP:
16024 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16025 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016026
Jeff Johnson295189b2012-06-20 16:38:30 -070016027 case WLAN_CIPHER_SUITE_CCMP:
16028 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16029 break;
16030#ifdef FEATURE_WLAN_WAPI
16031 case WLAN_CIPHER_SUITE_SMS4:
16032 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16033 break;
16034#endif
16035
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016036#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016037 case WLAN_CIPHER_SUITE_KRK:
16038 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16039 break;
16040#endif
16041 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 __func__, cipher);
16044 return -EOPNOTSUPP;
16045 }
16046 }
16047
16048 if (ucast)
16049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016051 __func__, encryptionType);
16052 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16053 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016054 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016055 encryptionType;
16056 }
16057 else
16058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 __func__, encryptionType);
16061 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16062 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16063 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16064 }
16065
16066 return 0;
16067}
16068
16069
16070/*
16071 * FUNCTION: wlan_hdd_cfg80211_set_ie
16072 * This function is used to parse WPA/RSN IE's.
16073 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016074int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16076 const u8 *ie,
16077#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016078 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016079#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016080 size_t ie_len
16081 )
16082{
16083 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16085 const u8 *genie = ie;
16086#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016088#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 v_U16_t remLen = ie_len;
16090#ifdef FEATURE_WLAN_WAPI
16091 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16092 u16 *tmp;
16093 v_U16_t akmsuiteCount;
16094 int *akmlist;
16095#endif
16096 ENTER();
16097
16098 /* clear previous assocAddIE */
16099 pWextState->assocAddIE.length = 0;
16100 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016101 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016102
16103 while (remLen >= 2)
16104 {
16105 v_U16_t eLen = 0;
16106 v_U8_t elementId;
16107 elementId = *genie++;
16108 eLen = *genie++;
16109 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016110
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016111 /* Sanity check on eLen */
16112 if (eLen > remLen) {
16113 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16114 __func__, eLen, elementId);
16115 VOS_ASSERT(0);
16116 return -EINVAL;
16117 }
16118
Arif Hussain6d2a3322013-11-17 19:50:10 -080016119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016120 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016121
16122 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016124 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016125 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 -070016126 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016127 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016128 "%s: Invalid WPA IE", __func__);
16129 return -EINVAL;
16130 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016131 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016132 {
16133 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016134 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016135 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016136
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016137 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016138 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016139 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16140 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 VOS_ASSERT(0);
16142 return -ENOMEM;
16143 }
16144 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16145 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16146 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016147
Jeff Johnson295189b2012-06-20 16:38:30 -070016148 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16149 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16150 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16151 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016152 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16153 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016154 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16155 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16156 __func__, eLen);
16157 VOS_ASSERT(0);
16158 return -EINVAL;
16159 }
16160
Jeff Johnson295189b2012-06-20 16:38:30 -070016161 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16162 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16163 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16164 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16165 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16166 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016167 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016168 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016169 {
16170 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016171 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016173
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016174 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016175 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016176 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16177 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 VOS_ASSERT(0);
16179 return -ENOMEM;
16180 }
16181 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16182 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16183 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016184
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16186 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16187 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016188#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016189 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16190 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016191 /*Consider WFD IE, only for P2P Client */
16192 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16193 {
16194 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016195 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016196 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016197
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016198 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016200 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16201 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016202 VOS_ASSERT(0);
16203 return -ENOMEM;
16204 }
16205 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16206 // WPS IE + P2P IE + WFD IE
16207 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16208 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016209
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16211 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16212 }
16213#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016214 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016215 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016216 HS20_OUI_TYPE_SIZE)) )
16217 {
16218 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016219 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016220 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016221
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016222 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016223 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016224 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16225 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016226 VOS_ASSERT(0);
16227 return -ENOMEM;
16228 }
16229 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16230 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016231
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016232 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16233 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16234 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016235 /* Appending OSEN Information Element in Assiciation Request */
16236 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16237 OSEN_OUI_TYPE_SIZE)) )
16238 {
16239 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16240 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16241 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016242
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016243 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016244 {
16245 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16246 "Need bigger buffer space");
16247 VOS_ASSERT(0);
16248 return -ENOMEM;
16249 }
16250 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16251 pWextState->assocAddIE.length += eLen + 2;
16252
16253 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16254 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16255 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16256 }
16257
Abhishek Singh4322e622015-06-10 15:42:54 +053016258 /* Update only for WPA IE */
16259 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16260 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016261
16262 /* populating as ADDIE in beacon frames */
16263 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016264 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016265 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16266 {
16267 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16268 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16269 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16270 {
16271 hddLog(LOGE,
16272 "Coldn't pass "
16273 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16274 }
16275 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16276 else
16277 hddLog(LOGE,
16278 "Could not pass on "
16279 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16280
16281 /* IBSS mode doesn't contain params->proberesp_ies still
16282 beaconIE's need to be populated in probe response frames */
16283 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16284 {
16285 u16 rem_probe_resp_ie_len = eLen + 2;
16286 u8 probe_rsp_ie_len[3] = {0};
16287 u8 counter = 0;
16288
16289 /* Check Probe Resp Length if it is greater then 255 then
16290 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16291 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16292 not able Store More then 255 bytes into One Variable */
16293
16294 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16295 {
16296 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16297 {
16298 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16299 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16300 }
16301 else
16302 {
16303 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16304 rem_probe_resp_ie_len = 0;
16305 }
16306 }
16307
16308 rem_probe_resp_ie_len = 0;
16309
16310 if (probe_rsp_ie_len[0] > 0)
16311 {
16312 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16313 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16314 (tANI_U8*)(genie - 2),
16315 probe_rsp_ie_len[0], NULL,
16316 eANI_BOOLEAN_FALSE)
16317 == eHAL_STATUS_FAILURE)
16318 {
16319 hddLog(LOGE,
16320 "Could not pass"
16321 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16322 }
16323 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16324 }
16325
16326 if (probe_rsp_ie_len[1] > 0)
16327 {
16328 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16329 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16330 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16331 probe_rsp_ie_len[1], NULL,
16332 eANI_BOOLEAN_FALSE)
16333 == eHAL_STATUS_FAILURE)
16334 {
16335 hddLog(LOGE,
16336 "Could not pass"
16337 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16338 }
16339 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16340 }
16341
16342 if (probe_rsp_ie_len[2] > 0)
16343 {
16344 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16345 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16346 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16347 probe_rsp_ie_len[2], NULL,
16348 eANI_BOOLEAN_FALSE)
16349 == eHAL_STATUS_FAILURE)
16350 {
16351 hddLog(LOGE,
16352 "Could not pass"
16353 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16354 }
16355 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16356 }
16357
16358 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16359 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16360 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16361 {
16362 hddLog(LOGE,
16363 "Could not pass"
16364 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16365 }
16366 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016367 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016368 break;
16369 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016370 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16371 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16372 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16373 VOS_ASSERT(0);
16374 return -EINVAL;
16375 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016376 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN 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.pRSNReqIE = pWextState->WPARSNIE;
16380 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16381 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016382
Abhishek Singhb16f3562016-01-20 11:08:32 +053016383 /* Appending extended capabilities with Interworking or
16384 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016385 *
16386 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016387 * interworkingService or bsstransition bit is set to 1.
16388 * Driver is only interested in interworkingService and
16389 * bsstransition capability from supplicant.
16390 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016391 * required from supplicat, it needs to be handled while
16392 * sending Assoc Req in LIM.
16393 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016394 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016395 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016396 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016397 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016398 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016399
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016400 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016401 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016402 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16403 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016404 VOS_ASSERT(0);
16405 return -ENOMEM;
16406 }
16407 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16408 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016409
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016410 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16411 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16412 break;
16413 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016414#ifdef FEATURE_WLAN_WAPI
16415 case WLAN_EID_WAPI:
16416 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016417 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016418 pAdapter->wapi_info.nWapiMode);
16419 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016420 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016421 akmsuiteCount = WPA_GET_LE16(tmp);
16422 tmp = tmp + 1;
16423 akmlist = (int *)(tmp);
16424 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16425 {
16426 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16427 }
16428 else
16429 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016430 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 VOS_ASSERT(0);
16432 return -EINVAL;
16433 }
16434
16435 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16436 {
16437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016438 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016439 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016440 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016442 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016443 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016444 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016445 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16446 }
16447 break;
16448#endif
16449 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016450 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016451 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016452 /* when Unknown IE is received we should break and continue
16453 * to the next IE in the buffer instead we were returning
16454 * so changing this to break */
16455 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016456 }
16457 genie += eLen;
16458 remLen -= eLen;
16459 }
16460 EXIT();
16461 return 0;
16462}
16463
16464/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016465 * FUNCTION: hdd_isWPAIEPresent
16466 * Parse the received IE to find the WPA IE
16467 *
16468 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016469static bool hdd_isWPAIEPresent(
16470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16471 const u8 *ie,
16472#else
16473 u8 *ie,
16474#endif
16475 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016476{
16477 v_U8_t eLen = 0;
16478 v_U16_t remLen = ie_len;
16479 v_U8_t elementId = 0;
16480
16481 while (remLen >= 2)
16482 {
16483 elementId = *ie++;
16484 eLen = *ie++;
16485 remLen -= 2;
16486 if (eLen > remLen)
16487 {
16488 hddLog(VOS_TRACE_LEVEL_ERROR,
16489 "%s: IE length is wrong %d", __func__, eLen);
16490 return FALSE;
16491 }
16492 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16493 {
16494 /* OUI - 0x00 0X50 0XF2
16495 WPA Information Element - 0x01
16496 WPA version - 0x01*/
16497 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16498 return TRUE;
16499 }
16500 ie += eLen;
16501 remLen -= eLen;
16502 }
16503 return FALSE;
16504}
16505
16506/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016507 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016508 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016509 * parameters during connect operation.
16510 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016511int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016512 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016513 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016514{
16515 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016516 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016517 ENTER();
16518
16519 /*set wpa version*/
16520 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16521
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016522 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016523 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016524 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016525 {
16526 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16527 }
16528 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16529 {
16530 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16531 }
16532 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533
16534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016535 pWextState->wpaVersion);
16536
16537 /*set authentication type*/
16538 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16539
16540 if (0 > status)
16541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016542 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016543 "%s: failed to set authentication type ", __func__);
16544 return status;
16545 }
16546
16547 /*set key mgmt type*/
16548 if (req->crypto.n_akm_suites)
16549 {
16550 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16551 if (0 > status)
16552 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016554 __func__);
16555 return status;
16556 }
16557 }
16558
16559 /*set pairwise cipher type*/
16560 if (req->crypto.n_ciphers_pairwise)
16561 {
16562 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16563 req->crypto.ciphers_pairwise[0], true);
16564 if (0 > status)
16565 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016566 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016567 "%s: failed to set unicast cipher type", __func__);
16568 return status;
16569 }
16570 }
16571 else
16572 {
16573 /*Reset previous cipher suite to none*/
16574 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16575 if (0 > status)
16576 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016577 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 "%s: failed to set unicast cipher type", __func__);
16579 return status;
16580 }
16581 }
16582
16583 /*set group cipher type*/
16584 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16585 false);
16586
16587 if (0 > status)
16588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016590 __func__);
16591 return status;
16592 }
16593
Chet Lanctot186b5732013-03-18 10:26:30 -070016594#ifdef WLAN_FEATURE_11W
16595 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16596#endif
16597
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16599 if (req->ie_len)
16600 {
16601 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16602 if ( 0 > status)
16603 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016604 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016605 __func__);
16606 return status;
16607 }
16608 }
16609
16610 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016611 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016612 {
16613 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16614 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16615 )
16616 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016617 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016618 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16619 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016620 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016621 __func__);
16622 return -EOPNOTSUPP;
16623 }
16624 else
16625 {
16626 u8 key_len = req->key_len;
16627 u8 key_idx = req->key_idx;
16628
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016629 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 && (CSR_MAX_NUM_KEY > key_idx)
16631 )
16632 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016633 hddLog(VOS_TRACE_LEVEL_INFO,
16634 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016635 __func__, key_idx, key_len);
16636 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016637 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016638 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016639 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016640 (u8)key_len;
16641 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16642 }
16643 }
16644 }
16645 }
16646
16647 return status;
16648}
16649
16650/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016651 * FUNCTION: wlan_hdd_try_disconnect
16652 * This function is used to disconnect from previous
16653 * connection
16654 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016655int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016656{
16657 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016658 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016659 hdd_station_ctx_t *pHddStaCtx;
16660 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016661 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016662
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016663 ret = wlan_hdd_validate_context(pHddCtx);
16664 if (0 != ret)
16665 {
16666 return ret;
16667 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016668 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16669
16670 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16671
16672 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16673 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016674 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016675 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16676 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016677 /* Indicate disconnect to SME so that in-progress connection or preauth
16678 * can be aborted
16679 */
16680 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16681 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016682 spin_lock_bh(&pAdapter->lock_for_active_session);
16683 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16684 {
16685 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16686 }
16687 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016688 hdd_connSetConnectionState(pHddStaCtx,
16689 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016690 /* Issue disconnect to CSR */
16691 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016692 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016693 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016694 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16695 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16696 hddLog(LOG1,
16697 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16698 } else if ( 0 != status ) {
16699 hddLog(LOGE,
16700 FL("csrRoamDisconnect failure, returned %d"),
16701 (int)status );
16702 result = -EINVAL;
16703 goto disconnected;
16704 }
16705 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016706 &pAdapter->disconnect_comp_var,
16707 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016708 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16709 hddLog(LOGE,
16710 "%s: Failed to disconnect, timed out", __func__);
16711 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016712 }
16713 }
16714 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16715 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016716 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016717 &pAdapter->disconnect_comp_var,
16718 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016719 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016720 {
16721 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016722 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016723 }
16724 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016725disconnected:
16726 hddLog(LOG1,
16727 FL("Set HDD connState to eConnectionState_NotConnected"));
16728 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16729 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016730}
16731
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016732/**
16733 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16734 * @adapter: Pointer to the HDD adapter
16735 * @req: Pointer to the structure cfg_connect_params receieved from user space
16736 *
16737 * This function will start reassociation if bssid hint, channel hint and
16738 * previous bssid parameters are present in the connect request
16739 *
16740 * Return: success if reassociation is happening
16741 * Error code if reassociation is not permitted or not happening
16742 */
16743#ifdef CFG80211_CONNECT_PREV_BSSID
16744static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16745 struct cfg80211_connect_params *req)
16746{
16747 int status = -EPERM;
16748 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16749 hddLog(VOS_TRACE_LEVEL_INFO,
16750 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16751 req->channel_hint->hw_value,
16752 MAC_ADDR_ARRAY(req->bssid_hint));
16753 status = hdd_reassoc(adapter, req->bssid_hint,
16754 req->channel_hint->hw_value,
16755 CONNECT_CMD_USERSPACE);
16756 }
16757 return status;
16758}
16759#else
16760static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16761 struct cfg80211_connect_params *req)
16762{
16763 return -EPERM;
16764}
16765#endif
16766
Abhishek Singhe3beee22017-07-31 15:35:40 +053016767/**
16768 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16769 * connect in HT20 mode
16770 * @hdd_ctx: hdd context
16771 * @adapter: Pointer to the HDD adapter
16772 * @req: Pointer to the structure cfg_connect_params receieved from user space
16773 *
16774 * This function will check if supplicant has indicated to to connect in HT20
16775 * mode. this is currently applicable only for 2.4Ghz mode only.
16776 * if feature is enabled and supplicant indicate HT20 set
16777 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16778 *
16779 * Return: void
16780 */
16781#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16782static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16783 hdd_adapter_t *adapter,
16784 struct cfg80211_connect_params *req)
16785{
16786 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16787 tCsrRoamProfile *roam_profile;
16788
16789 roam_profile = &wext_state->roamProfile;
16790 roam_profile->force_24ghz_in_ht20 = false;
16791 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16792 !(req->ht_capa.cap_info &
16793 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16794 roam_profile->force_24ghz_in_ht20 = true;
16795
16796 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16797 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16798}
16799#else
16800static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16801 hdd_adapter_t *adapter,
16802 struct cfg80211_connect_params *req)
16803{
16804 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16805 tCsrRoamProfile *roam_profile;
16806
16807 roam_profile = &wext_state->roamProfile;
16808 roam_profile->force_24ghz_in_ht20 = false;
16809}
16810#endif
16811
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016812/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016813 * FUNCTION: __wlan_hdd_cfg80211_connect
16814 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016815 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016816static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016817 struct net_device *ndev,
16818 struct cfg80211_connect_params *req
16819 )
16820{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016821 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016822 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016823#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16824 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016825 const u8 *bssid_hint = req->bssid_hint;
16826#else
16827 const u8 *bssid_hint = NULL;
16828#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016829 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016831 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016832
16833 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016834
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016835 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16836 TRACE_CODE_HDD_CFG80211_CONNECT,
16837 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016838 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016839 "%s: device_mode = %s (%d)", __func__,
16840 hdd_device_modetoString(pAdapter->device_mode),
16841 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016842
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016843 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016844 if (!pHddCtx)
16845 {
16846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16847 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016848 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016849 }
16850
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016851 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016852 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016854 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016855 }
16856
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016857 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16858 return -EINVAL;
16859
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016860 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16861 if (0 == status)
16862 return status;
16863
Agarwal Ashish51325b52014-06-16 16:50:49 +053016864
Jeff Johnson295189b2012-06-20 16:38:30 -070016865#ifdef WLAN_BTAMP_FEATURE
16866 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016867 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016869 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016870 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016871 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016872 }
16873#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016874
16875 //If Device Mode is Station Concurrent Sessions Exit BMps
16876 //P2P Mode will be taken care in Open/close adapter
16877 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016878 (vos_concurrent_open_sessions_running())) {
16879 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16880 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016881 }
16882
16883 /*Try disconnecting if already in connected state*/
16884 status = wlan_hdd_try_disconnect(pAdapter);
16885 if ( 0 > status)
16886 {
16887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16888 " connection"));
16889 return -EALREADY;
16890 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016891 /* Check for max concurrent connections after doing disconnect if any*/
16892 if (vos_max_concurrent_connections_reached()) {
16893 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16894 return -ECONNREFUSED;
16895 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016896
Jeff Johnson295189b2012-06-20 16:38:30 -070016897 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016898 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016899
16900 if ( 0 > status)
16901 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016903 __func__);
16904 return status;
16905 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016906
16907 if (pHddCtx->spoofMacAddr.isEnabled)
16908 {
16909 hddLog(VOS_TRACE_LEVEL_INFO,
16910 "%s: MAC Spoofing enabled ", __func__);
16911 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16912 * to fill TxBds for probe request during SSID scan which may happen
16913 * as part of connect command
16914 */
16915 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16916 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16917 if (status != VOS_STATUS_SUCCESS)
16918 return -ECONNREFUSED;
16919 }
16920
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016921 if (req->channel)
16922 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016923 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016924 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016925
16926 /* Abort if any scan is going on */
16927 status = wlan_hdd_scan_abort(pAdapter);
16928 if (0 != status)
16929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16930
Abhishek Singhe3beee22017-07-31 15:35:40 +053016931 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16932
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016933 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16934 req->ssid_len, req->bssid,
16935 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016936
Sushant Kaushikd7083982015-03-18 14:33:24 +053016937 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016938 {
16939 //ReEnable BMPS if disabled
16940 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16941 (NULL != pHddCtx))
16942 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016943 if (pHddCtx->hdd_wlan_suspended)
16944 {
16945 hdd_set_pwrparams(pHddCtx);
16946 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016947 //ReEnable Bmps and Imps back
16948 hdd_enable_bmps_imps(pHddCtx);
16949 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016951 return status;
16952 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016953 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016954 EXIT();
16955 return status;
16956}
16957
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016958static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16959 struct net_device *ndev,
16960 struct cfg80211_connect_params *req)
16961{
16962 int ret;
16963 vos_ssr_protect(__func__);
16964 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16965 vos_ssr_unprotect(__func__);
16966
16967 return ret;
16968}
Jeff Johnson295189b2012-06-20 16:38:30 -070016969
16970/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016971 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 * This function is used to issue a disconnect request to SME
16973 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016974static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016975 struct net_device *dev,
16976 u16 reason
16977 )
16978{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016980 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016981 tCsrRoamProfile *pRoamProfile;
16982 hdd_station_ctx_t *pHddStaCtx;
16983 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016984#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016985 tANI_U8 staIdx;
16986#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016987
Jeff Johnson295189b2012-06-20 16:38:30 -070016988 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016989
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016990 if (!pAdapter) {
16991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16992 return -EINVAL;
16993 }
16994
16995 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16996 if (!pHddStaCtx) {
16997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16998 return -EINVAL;
16999 }
17000
17001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17002 status = wlan_hdd_validate_context(pHddCtx);
17003 if (0 != status)
17004 {
17005 return status;
17006 }
17007
17008 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17009
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017010 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17011 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17012 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017013 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17014 __func__, hdd_device_modetoString(pAdapter->device_mode),
17015 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017016
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17018 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017019
Jeff Johnson295189b2012-06-20 16:38:30 -070017020 if (NULL != pRoamProfile)
17021 {
17022 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017023 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17024 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017026 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017028 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 switch(reason)
17030 {
17031 case WLAN_REASON_MIC_FAILURE:
17032 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17033 break;
17034
17035 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17036 case WLAN_REASON_DISASSOC_AP_BUSY:
17037 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17038 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17039 break;
17040
17041 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17042 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017043 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017044 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17045 break;
17046
Jeff Johnson295189b2012-06-20 16:38:30 -070017047 default:
17048 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17049 break;
17050 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017051 pScanInfo = &pHddCtx->scan_info;
17052 if (pScanInfo->mScanPending)
17053 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017054 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017055 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017056 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017057 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017058 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017059 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017060#ifdef FEATURE_WLAN_TDLS
17061 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017062 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017063 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017064 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17065 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017066 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017067 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017068 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017070 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017071 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017072 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017073 status = sme_DeleteTdlsPeerSta(
17074 WLAN_HDD_GET_HAL_CTX(pAdapter),
17075 pAdapter->sessionId,
17076 mac);
17077 if (status != eHAL_STATUS_SUCCESS) {
17078 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17079 return -EPERM;
17080 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017081 }
17082 }
17083#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017084
17085 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17086 reasonCode,
17087 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017088 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17089 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017090 {
17091 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017092 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 __func__, (int)status );
17094 return -EINVAL;
17095 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017096 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017097 else
17098 {
17099 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17100 "called while in %d state", __func__,
17101 pHddStaCtx->conn_info.connState);
17102 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017103 }
17104 else
17105 {
17106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17107 }
17108
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017109 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017110 return status;
17111}
17112
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017113static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17114 struct net_device *dev,
17115 u16 reason
17116 )
17117{
17118 int ret;
17119 vos_ssr_protect(__func__);
17120 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17121 vos_ssr_unprotect(__func__);
17122
17123 return ret;
17124}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017125
Jeff Johnson295189b2012-06-20 16:38:30 -070017126/*
17127 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017128 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017129 * settings in IBSS mode.
17130 */
17131static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017132 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017133 struct cfg80211_ibss_params *params
17134 )
17135{
17136 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017137 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017138 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17139 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017140
Jeff Johnson295189b2012-06-20 16:38:30 -070017141 ENTER();
17142
17143 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017144 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017145
17146 if (params->ie_len && ( NULL != params->ie) )
17147 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017148 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17149 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017150 {
17151 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17152 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17153 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017154 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017155 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017156 tDot11fIEWPA dot11WPAIE;
17157 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017158 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017159
Wilson Yang00256342013-10-10 23:13:38 -070017160 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017161 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17162 params->ie_len, DOT11F_EID_WPA);
17163 if ( NULL != ie )
17164 {
17165 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17166 // Unpack the WPA IE
17167 //Skip past the EID byte and length byte - and four byte WiFi OUI
17168 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
17169 &ie[2+4],
17170 ie[1] - 4,
17171 &dot11WPAIE);
17172 /*Extract the multicast cipher, the encType for unicast
17173 cipher for wpa-none is none*/
17174 encryptionType =
17175 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17176 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017178
Jeff Johnson295189b2012-06-20 16:38:30 -070017179 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17180
17181 if (0 > status)
17182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017184 __func__);
17185 return status;
17186 }
17187 }
17188
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017189 pWextState->roamProfile.AuthType.authType[0] =
17190 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017191 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 if (params->privacy)
17193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017194 /* Security enabled IBSS, At this time there is no information available
17195 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017196 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017197 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017198 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017199 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017200 *enable privacy bit in beacons */
17201
17202 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17203 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017204 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17205 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017206 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17207 pWextState->roamProfile.EncryptionType.numEntries = 1;
17208 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017209 return status;
17210}
17211
17212/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017213 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017214 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017215 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017216static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017217 struct net_device *dev,
17218 struct cfg80211_ibss_params *params
17219 )
17220{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017221 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017222 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17223 tCsrRoamProfile *pRoamProfile;
17224 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017225 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017227 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017228
17229 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017230
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017231 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17232 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17233 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017234 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017235 "%s: device_mode = %s (%d)", __func__,
17236 hdd_device_modetoString(pAdapter->device_mode),
17237 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017238
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017239 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017240 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017241 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017242 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017243 }
17244
17245 if (NULL == pWextState)
17246 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017247 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017248 __func__);
17249 return -EIO;
17250 }
17251
Agarwal Ashish51325b52014-06-16 16:50:49 +053017252 if (vos_max_concurrent_connections_reached()) {
17253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17254 return -ECONNREFUSED;
17255 }
17256
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017257 /*Try disconnecting if already in connected state*/
17258 status = wlan_hdd_try_disconnect(pAdapter);
17259 if ( 0 > status)
17260 {
17261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17262 " IBSS connection"));
17263 return -EALREADY;
17264 }
17265
Jeff Johnson295189b2012-06-20 16:38:30 -070017266 pRoamProfile = &pWextState->roamProfile;
17267
17268 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017270 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017271 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017272 return -EINVAL;
17273 }
17274
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017275 /* BSSID is provided by upper layers hence no need to AUTO generate */
17276 if (NULL != params->bssid) {
17277 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17278 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17279 hddLog (VOS_TRACE_LEVEL_ERROR,
17280 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17281 return -EIO;
17282 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017283 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017284 }
krunal sonie9002db2013-11-25 14:24:17 -080017285 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17286 {
17287 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17288 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17289 {
17290 hddLog (VOS_TRACE_LEVEL_ERROR,
17291 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17292 return -EIO;
17293 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017294
17295 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017296 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017297 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017298 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017299
Jeff Johnson295189b2012-06-20 16:38:30 -070017300 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017301 if (NULL !=
17302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17303 params->chandef.chan)
17304#else
17305 params->channel)
17306#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017307 {
17308 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017309 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17310 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17311 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17312 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017313
17314 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017315 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017316 ieee80211_frequency_to_channel(
17317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17318 params->chandef.chan->center_freq);
17319#else
17320 params->channel->center_freq);
17321#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017322
17323 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17324 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017325 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017326 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17327 __func__);
17328 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017329 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017330
17331 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017332 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017333 if (channelNum == validChan[indx])
17334 {
17335 break;
17336 }
17337 }
17338 if (indx >= numChans)
17339 {
17340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 __func__, channelNum);
17342 return -EINVAL;
17343 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017344 /* Set the Operational Channel */
17345 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17346 channelNum);
17347 pRoamProfile->ChannelInfo.numOfChannels = 1;
17348 pHddStaCtx->conn_info.operationChannel = channelNum;
17349 pRoamProfile->ChannelInfo.ChannelList =
17350 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017351 }
17352
17353 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017354 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017355 if (status < 0)
17356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017358 __func__);
17359 return status;
17360 }
17361
17362 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017363 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017364 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017365 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017366
17367 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017370 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017371 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017372}
17373
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017374static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17375 struct net_device *dev,
17376 struct cfg80211_ibss_params *params
17377 )
17378{
17379 int ret = 0;
17380
17381 vos_ssr_protect(__func__);
17382 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17383 vos_ssr_unprotect(__func__);
17384
17385 return ret;
17386}
17387
Jeff Johnson295189b2012-06-20 16:38:30 -070017388/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017389 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017390 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017391 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017392static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017393 struct net_device *dev
17394 )
17395{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017396 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017397 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17398 tCsrRoamProfile *pRoamProfile;
17399 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017400 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017401 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017402#ifdef WLAN_FEATURE_RMC
17403 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017405
17406 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017407
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017408 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17409 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17410 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017411 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017412 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017413 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017414 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017415 }
17416
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17418 hdd_device_modetoString(pAdapter->device_mode),
17419 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017420 if (NULL == pWextState)
17421 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017422 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 __func__);
17424 return -EIO;
17425 }
17426
17427 pRoamProfile = &pWextState->roamProfile;
17428
17429 /* Issue disconnect only if interface type is set to IBSS */
17430 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017432 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 __func__);
17434 return -EINVAL;
17435 }
17436
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017437#ifdef WLAN_FEATURE_RMC
17438 /* Clearing add IE of beacon */
17439 if (ccmCfgSetStr(pHddCtx->hHal,
17440 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17441 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17442 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17443 {
17444 hddLog (VOS_TRACE_LEVEL_ERROR,
17445 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17446 return -EINVAL;
17447 }
17448 if (ccmCfgSetInt(pHddCtx->hHal,
17449 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17450 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17451 {
17452 hddLog (VOS_TRACE_LEVEL_ERROR,
17453 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17454 __func__);
17455 return -EINVAL;
17456 }
17457
17458 // Reset WNI_CFG_PROBE_RSP Flags
17459 wlan_hdd_reset_prob_rspies(pAdapter);
17460
17461 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17462 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17463 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17464 {
17465 hddLog (VOS_TRACE_LEVEL_ERROR,
17466 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17467 __func__);
17468 return -EINVAL;
17469 }
17470#endif
17471
Jeff Johnson295189b2012-06-20 16:38:30 -070017472 /* Issue Disconnect request */
17473 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017474 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17475 pAdapter->sessionId,
17476 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17477 if (!HAL_STATUS_SUCCESS(hal_status)) {
17478 hddLog(LOGE,
17479 FL("sme_RoamDisconnect failed hal_status(%d)"),
17480 hal_status);
17481 return -EAGAIN;
17482 }
17483 status = wait_for_completion_timeout(
17484 &pAdapter->disconnect_comp_var,
17485 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17486 if (!status) {
17487 hddLog(LOGE,
17488 FL("wait on disconnect_comp_var failed"));
17489 return -ETIMEDOUT;
17490 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017492 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017493 return 0;
17494}
17495
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017496static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17497 struct net_device *dev
17498 )
17499{
17500 int ret = 0;
17501
17502 vos_ssr_protect(__func__);
17503 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17504 vos_ssr_unprotect(__func__);
17505
17506 return ret;
17507}
17508
Jeff Johnson295189b2012-06-20 16:38:30 -070017509/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017510 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017511 * This function is used to set the phy parameters
17512 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17513 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017514static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017515 u32 changed)
17516{
17517 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17518 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017519 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017520
17521 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017522
17523 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017524 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17525 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017526
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017527 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017528 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017529 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017530 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017531 }
17532
Jeff Johnson295189b2012-06-20 16:38:30 -070017533 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17534 {
17535 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17536 WNI_CFG_RTS_THRESHOLD_STAMAX :
17537 wiphy->rts_threshold;
17538
17539 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017540 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017542 hddLog(VOS_TRACE_LEVEL_ERROR,
17543 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017544 __func__, rts_threshold);
17545 return -EINVAL;
17546 }
17547
17548 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17549 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017550 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017552 hddLog(VOS_TRACE_LEVEL_ERROR,
17553 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017554 __func__, rts_threshold);
17555 return -EIO;
17556 }
17557
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017558 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017559 rts_threshold);
17560 }
17561
17562 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17563 {
17564 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17565 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17566 wiphy->frag_threshold;
17567
17568 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017569 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017571 hddLog(VOS_TRACE_LEVEL_ERROR,
17572 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017573 frag_threshold);
17574 return -EINVAL;
17575 }
17576
17577 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17578 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017579 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017581 hddLog(VOS_TRACE_LEVEL_ERROR,
17582 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017583 __func__, frag_threshold);
17584 return -EIO;
17585 }
17586
17587 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17588 frag_threshold);
17589 }
17590
17591 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17592 || (changed & WIPHY_PARAM_RETRY_LONG))
17593 {
17594 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17595 wiphy->retry_short :
17596 wiphy->retry_long;
17597
17598 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17599 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017602 __func__, retry_value);
17603 return -EINVAL;
17604 }
17605
17606 if (changed & WIPHY_PARAM_RETRY_SHORT)
17607 {
17608 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17609 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017610 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017611 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017612 hddLog(VOS_TRACE_LEVEL_ERROR,
17613 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017614 __func__, retry_value);
17615 return -EIO;
17616 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017617 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017618 __func__, retry_value);
17619 }
17620 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17621 {
17622 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17623 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017624 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017625 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017626 hddLog(VOS_TRACE_LEVEL_ERROR,
17627 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017628 __func__, retry_value);
17629 return -EIO;
17630 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017631 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017632 __func__, retry_value);
17633 }
17634 }
17635
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017636 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 return 0;
17638}
17639
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017640static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17641 u32 changed)
17642{
17643 int ret;
17644
17645 vos_ssr_protect(__func__);
17646 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17647 vos_ssr_unprotect(__func__);
17648
17649 return ret;
17650}
17651
Jeff Johnson295189b2012-06-20 16:38:30 -070017652/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017653 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017654 * This function is used to set the txpower
17655 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017656static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017657#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17658 struct wireless_dev *wdev,
17659#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017660#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017661 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017662#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017663 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017664#endif
17665 int dbm)
17666{
17667 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017668 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017669 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17670 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017671 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017672
17673 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017674
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017675 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17676 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17677 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017678 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017679 if (0 != status)
17680 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017681 return status;
17682 }
17683
17684 hHal = pHddCtx->hHal;
17685
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017686 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17687 dbm, ccmCfgSetCallback,
17688 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017690 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017691 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17692 return -EIO;
17693 }
17694
17695 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17696 dbm);
17697
17698 switch(type)
17699 {
17700 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17701 /* Fall through */
17702 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17703 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17704 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17706 __func__);
17707 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017708 }
17709 break;
17710 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017711 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017712 __func__);
17713 return -EOPNOTSUPP;
17714 break;
17715 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17717 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017718 return -EIO;
17719 }
17720
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017721 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017722 return 0;
17723}
17724
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017725static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17726#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17727 struct wireless_dev *wdev,
17728#endif
17729#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17730 enum tx_power_setting type,
17731#else
17732 enum nl80211_tx_power_setting type,
17733#endif
17734 int dbm)
17735{
17736 int ret;
17737 vos_ssr_protect(__func__);
17738 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17739#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17740 wdev,
17741#endif
17742#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17743 type,
17744#else
17745 type,
17746#endif
17747 dbm);
17748 vos_ssr_unprotect(__func__);
17749
17750 return ret;
17751}
17752
Jeff Johnson295189b2012-06-20 16:38:30 -070017753/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017754 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017755 * This function is used to read the txpower
17756 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017757static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017758#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17759 struct wireless_dev *wdev,
17760#endif
17761 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017762{
17763
17764 hdd_adapter_t *pAdapter;
17765 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017766 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017767
Jeff Johnsone7245742012-09-05 17:12:55 -070017768 ENTER();
17769
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017770 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017771 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017772 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017773 *dbm = 0;
17774 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017775 }
17776
Jeff Johnson295189b2012-06-20 16:38:30 -070017777 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17778 if (NULL == pAdapter)
17779 {
17780 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17781 return -ENOENT;
17782 }
17783
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17785 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17786 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017787 wlan_hdd_get_classAstats(pAdapter);
17788 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17789
Jeff Johnsone7245742012-09-05 17:12:55 -070017790 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017791 return 0;
17792}
17793
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017794static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17795#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17796 struct wireless_dev *wdev,
17797#endif
17798 int *dbm)
17799{
17800 int ret;
17801
17802 vos_ssr_protect(__func__);
17803 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17804#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17805 wdev,
17806#endif
17807 dbm);
17808 vos_ssr_unprotect(__func__);
17809
17810 return ret;
17811}
17812
Dustin Brown8c1d4092017-07-28 18:08:01 +053017813/*
17814 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17815 * @stats: summary stats to use as a source
17816 * @info: kernel station_info struct to use as a destination
17817 *
17818 * Return: None
17819 */
17820static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17821 struct station_info *info)
17822{
17823 int i;
17824
17825 info->rx_packets = stats->rx_frm_cnt;
17826 info->tx_packets = 0;
17827 info->tx_retries = 0;
17828 info->tx_failed = 0;
17829
17830 for (i = 0; i < 4; ++i) {
17831 info->tx_packets += stats->tx_frm_cnt[i];
17832 info->tx_retries += stats->multiple_retry_cnt[i];
17833 info->tx_failed += stats->fail_cnt[i];
17834 }
17835
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017836#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17837 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017838 info->filled |= STATION_INFO_TX_PACKETS |
17839 STATION_INFO_TX_RETRIES |
17840 STATION_INFO_TX_FAILED |
17841 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017842#else
17843 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17844 BIT(NL80211_STA_INFO_TX_RETRIES) |
17845 BIT(NL80211_STA_INFO_TX_FAILED) |
17846 BIT(NL80211_STA_INFO_RX_PACKETS);
17847#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017848}
17849
17850/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017851 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17852 * @adapter: sap adapter pointer
17853 * @staid: station id of the client
17854 * @rssi: rssi value to fill
17855 *
17856 * Return: None
17857 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017858void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017859wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17860{
17861 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17862
17863 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17864}
17865
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017866#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17867 !defined(WITH_BACKPORTS)
17868static inline void wlan_hdd_fill_station_info_signal(struct station_info
17869 *sinfo)
17870{
17871 sinfo->filled |= STATION_INFO_SIGNAL;
17872}
17873#else
17874static inline void wlan_hdd_fill_station_info_signal(struct station_info
17875 *sinfo)
17876{
17877 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17878}
17879#endif
17880
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017881/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017882 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17883 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017884 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017885 * @info: kernel station_info struct to populate
17886 *
17887 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17888 * support "station dump" and "station get" for SAP vdevs, even though they
17889 * aren't technically stations.
17890 *
17891 * Return: errno
17892 */
17893static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017894wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17895#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17896 const u8* mac,
17897#else
17898 u8* mac,
17899#endif
17900 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017901{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017902 v_MACADDR_t *peerMacAddr;
17903 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017904 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017905 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017906
17907 status = wlan_hdd_get_station_stats(adapter);
17908 if (!VOS_IS_STATUS_SUCCESS(status)) {
17909 hddLog(VOS_TRACE_LEVEL_ERROR,
17910 "Failed to get SAP stats; status:%d", status);
17911 return 0;
17912 }
17913
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017914 peerMacAddr = (v_MACADDR_t *)mac;
17915 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17916 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17917 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17918
17919 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17920 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017921 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017922 }
17923
Dustin Brown8c1d4092017-07-28 18:08:01 +053017924 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17925
17926 return 0;
17927}
17928
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017929static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17931 const u8* mac,
17932#else
17933 u8* mac,
17934#endif
17935 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017936{
17937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17938 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17939 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017940 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017941
17942 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17943 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017944
17945 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17946 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17947 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17948 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17949 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17950 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17951 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017952 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 tANI_U16 myRate;
17954 tANI_U16 currentRate = 0;
17955 tANI_U8 maxSpeedMCS = 0;
17956 tANI_U8 maxMCSIdx = 0;
17957 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017958 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017959 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017960 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017961
Leo Chang6f8870f2013-03-26 18:11:36 -070017962#ifdef WLAN_FEATURE_11AC
17963 tANI_U32 vht_mcs_map;
17964 eDataRate11ACMaxMcs vhtMaxMcs;
17965#endif /* WLAN_FEATURE_11AC */
17966
Jeff Johnsone7245742012-09-05 17:12:55 -070017967 ENTER();
17968
Dustin Brown8c1d4092017-07-28 18:08:01 +053017969 status = wlan_hdd_validate_context(pHddCtx);
17970 if (0 != status)
17971 {
17972 return status;
17973 }
17974
17975 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017976 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017977
Jeff Johnson295189b2012-06-20 16:38:30 -070017978 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17979 (0 == ssidlen))
17980 {
17981 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17982 " Invalid ssidlen, %d", __func__, ssidlen);
17983 /*To keep GUI happy*/
17984 return 0;
17985 }
17986
Mukul Sharma811205f2014-07-09 21:07:30 +053017987 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17988 {
17989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17990 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017991 /* return a cached value */
17992 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017993 return 0;
17994 }
17995
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017996 wlan_hdd_get_station_stats(pAdapter);
17997 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017998
Kiet Lam3b17fc82013-09-27 05:24:08 +053017999 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018000 wlan_hdd_get_snr(pAdapter, &snr);
18001 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018002 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018003 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018004 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018005 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018006
c_hpothu09f19542014-05-30 21:53:31 +053018007 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018008 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18009 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018010 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018011 {
18012 rate_flags = pAdapter->maxRateFlags;
18013 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018014
Jeff Johnson295189b2012-06-20 16:38:30 -070018015 //convert to the UI units of 100kbps
18016 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18017
18018#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018019 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 -070018020 sinfo->signal,
18021 pCfg->reportMaxLinkSpeed,
18022 myRate,
18023 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018024 (int) pCfg->linkSpeedRssiMid,
18025 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018026 (int) rate_flags,
18027 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018028#endif //LINKSPEED_DEBUG_ENABLED
18029
18030 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18031 {
18032 // we do not want to necessarily report the current speed
18033 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18034 {
18035 // report the max possible speed
18036 rssidx = 0;
18037 }
18038 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18039 {
18040 // report the max possible speed with RSSI scaling
18041 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18042 {
18043 // report the max possible speed
18044 rssidx = 0;
18045 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018046 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018047 {
18048 // report middle speed
18049 rssidx = 1;
18050 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018051 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18052 {
18053 // report middle speed
18054 rssidx = 2;
18055 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018056 else
18057 {
18058 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018059 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018060 }
18061 }
18062 else
18063 {
18064 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18065 hddLog(VOS_TRACE_LEVEL_ERROR,
18066 "%s: Invalid value for reportMaxLinkSpeed: %u",
18067 __func__, pCfg->reportMaxLinkSpeed);
18068 rssidx = 0;
18069 }
18070
18071 maxRate = 0;
18072
18073 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018074 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18075 OperationalRates, &ORLeng))
18076 {
18077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18078 /*To keep GUI happy*/
18079 return 0;
18080 }
18081
Jeff Johnson295189b2012-06-20 16:38:30 -070018082 for (i = 0; i < ORLeng; i++)
18083 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018084 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018085 {
18086 /* Validate Rate Set */
18087 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18088 {
18089 currentRate = supported_data_rate[j].supported_rate[rssidx];
18090 break;
18091 }
18092 }
18093 /* Update MAX rate */
18094 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18095 }
18096
18097 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018098 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18099 ExtendedRates, &ERLeng))
18100 {
18101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18102 /*To keep GUI happy*/
18103 return 0;
18104 }
18105
Jeff Johnson295189b2012-06-20 16:38:30 -070018106 for (i = 0; i < ERLeng; i++)
18107 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018108 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018109 {
18110 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18111 {
18112 currentRate = supported_data_rate[j].supported_rate[rssidx];
18113 break;
18114 }
18115 }
18116 /* Update MAX rate */
18117 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18118 }
c_hpothu79aab322014-07-14 21:11:01 +053018119
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018120 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018121 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018122 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018123 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018124 {
c_hpothu79aab322014-07-14 21:11:01 +053018125 if (rate_flags & eHAL_TX_RATE_VHT80)
18126 mode = 2;
18127 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18128 mode = 1;
18129 else
18130 mode = 0;
18131
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018132 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18133 MCSRates, &MCSLeng))
18134 {
18135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18136 /*To keep GUI happy*/
18137 return 0;
18138 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018139 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018140#ifdef WLAN_FEATURE_11AC
18141 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018142 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018143 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018144 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018145 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018146 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018147 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018148 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018149 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018150 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018151 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018152 maxMCSIdx = 7;
18153 }
18154 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18155 {
18156 maxMCSIdx = 8;
18157 }
18158 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18159 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018160 //VHT20 is supporting 0~8
18161 if (rate_flags & eHAL_TX_RATE_VHT20)
18162 maxMCSIdx = 8;
18163 else
18164 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018165 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018166
c_hpothu79aab322014-07-14 21:11:01 +053018167 if (0 != rssidx)/*check for scaled */
18168 {
18169 //get middle rate MCS index if rssi=1/2
18170 for (i=0; i <= maxMCSIdx; i++)
18171 {
18172 if (sinfo->signal <= rssiMcsTbl[mode][i])
18173 {
18174 maxMCSIdx = i;
18175 break;
18176 }
18177 }
18178 }
18179
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018180 if (rate_flags & eHAL_TX_RATE_VHT80)
18181 {
18182 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18183 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18184 }
18185 else if (rate_flags & eHAL_TX_RATE_VHT40)
18186 {
18187 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18188 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18189 }
18190 else if (rate_flags & eHAL_TX_RATE_VHT20)
18191 {
18192 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18193 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18194 }
18195
Leo Chang6f8870f2013-03-26 18:11:36 -070018196 maxSpeedMCS = 1;
18197 if (currentRate > maxRate)
18198 {
18199 maxRate = currentRate;
18200 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018201
Leo Chang6f8870f2013-03-26 18:11:36 -070018202 }
18203 else
18204#endif /* WLAN_FEATURE_11AC */
18205 {
18206 if (rate_flags & eHAL_TX_RATE_HT40)
18207 {
18208 rateFlag |= 1;
18209 }
18210 if (rate_flags & eHAL_TX_RATE_SGI)
18211 {
18212 rateFlag |= 2;
18213 }
18214
Girish Gowli01abcee2014-07-31 20:18:55 +053018215 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018216 if (rssidx == 1 || rssidx == 2)
18217 {
18218 //get middle rate MCS index if rssi=1/2
18219 for (i=0; i <= 7; i++)
18220 {
18221 if (sinfo->signal <= rssiMcsTbl[mode][i])
18222 {
18223 temp = i+1;
18224 break;
18225 }
18226 }
18227 }
c_hpothu79aab322014-07-14 21:11:01 +053018228
18229 for (i = 0; i < MCSLeng; i++)
18230 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018231 for (j = 0; j < temp; j++)
18232 {
18233 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18234 {
18235 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018236 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018237 break;
18238 }
18239 }
18240 if ((j < temp) && (currentRate > maxRate))
18241 {
18242 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018243 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018244 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018245 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018246 }
18247 }
18248
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018249 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18250 {
18251 maxRate = myRate;
18252 maxSpeedMCS = 1;
18253 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18254 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018255 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018256 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018257 {
18258 maxRate = myRate;
18259 if (rate_flags & eHAL_TX_RATE_LEGACY)
18260 {
18261 maxSpeedMCS = 0;
18262 }
18263 else
18264 {
18265 maxSpeedMCS = 1;
18266 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18267 }
18268 }
18269
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018270 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018271 {
18272 sinfo->txrate.legacy = maxRate;
18273#ifdef LINKSPEED_DEBUG_ENABLED
18274 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18275#endif //LINKSPEED_DEBUG_ENABLED
18276 }
18277 else
18278 {
18279 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018280#ifdef WLAN_FEATURE_11AC
18281 sinfo->txrate.nss = 1;
18282 if (rate_flags & eHAL_TX_RATE_VHT80)
18283 {
18284 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18286 defined(WITH_BACKPORTS)
18287 sinfo->txrate.bw = RATE_INFO_BW_80;
18288#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018289 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018290#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018291 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018292 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018293 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018294 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018295#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18296 defined(WITH_BACKPORTS)
18297 sinfo->txrate.bw = RATE_INFO_BW_40;
18298#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018299 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018300#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018301 }
18302 else if (rate_flags & eHAL_TX_RATE_VHT20)
18303 {
18304 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18305 }
18306#endif /* WLAN_FEATURE_11AC */
18307 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18308 {
18309 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18310 if (rate_flags & eHAL_TX_RATE_HT40)
18311 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018312#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18313 defined(WITH_BACKPORTS)
18314 sinfo->txrate.bw = RATE_INFO_BW_40;
18315#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018316 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018317#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018318 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018319 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018320 if (rate_flags & eHAL_TX_RATE_SGI)
18321 {
18322 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18323 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018324
Jeff Johnson295189b2012-06-20 16:38:30 -070018325#ifdef LINKSPEED_DEBUG_ENABLED
18326 pr_info("Reporting MCS rate %d flags %x\n",
18327 sinfo->txrate.mcs,
18328 sinfo->txrate.flags );
18329#endif //LINKSPEED_DEBUG_ENABLED
18330 }
18331 }
18332 else
18333 {
18334 // report current rate instead of max rate
18335
18336 if (rate_flags & eHAL_TX_RATE_LEGACY)
18337 {
18338 //provide to the UI in units of 100kbps
18339 sinfo->txrate.legacy = myRate;
18340#ifdef LINKSPEED_DEBUG_ENABLED
18341 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18342#endif //LINKSPEED_DEBUG_ENABLED
18343 }
18344 else
18345 {
18346 //must be MCS
18347 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018348#ifdef WLAN_FEATURE_11AC
18349 sinfo->txrate.nss = 1;
18350 if (rate_flags & eHAL_TX_RATE_VHT80)
18351 {
18352 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18353 }
18354 else
18355#endif /* WLAN_FEATURE_11AC */
18356 {
18357 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18358 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018359 if (rate_flags & eHAL_TX_RATE_SGI)
18360 {
18361 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18362 }
18363 if (rate_flags & eHAL_TX_RATE_HT40)
18364 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18366 defined(WITH_BACKPORTS)
18367 sinfo->txrate.bw = RATE_INFO_BW_40;
18368#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018369 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018370#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018371 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018372#ifdef WLAN_FEATURE_11AC
18373 else if (rate_flags & eHAL_TX_RATE_VHT80)
18374 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018375#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18376 defined(WITH_BACKPORTS)
18377 sinfo->txrate.bw = RATE_INFO_BW_80;
18378#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018379 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018380#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018381 }
18382#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018383#ifdef LINKSPEED_DEBUG_ENABLED
18384 pr_info("Reporting actual MCS rate %d flags %x\n",
18385 sinfo->txrate.mcs,
18386 sinfo->txrate.flags );
18387#endif //LINKSPEED_DEBUG_ENABLED
18388 }
18389 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018390
18391#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18392 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018393 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018394#else
18395 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18396#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018397
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018398 sinfo->tx_packets =
18399 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18400 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18401 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18402 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18403
18404 sinfo->tx_retries =
18405 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18406 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18407 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18408 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18409
18410 sinfo->tx_failed =
18411 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18412 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18413 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18414 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18415
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018416#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18417 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018418 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018419 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018420 STATION_INFO_TX_PACKETS |
18421 STATION_INFO_TX_RETRIES |
18422 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018423#else
18424 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18425 BIT(NL80211_STA_INFO_TX_PACKETS) |
18426 BIT(NL80211_STA_INFO_TX_RETRIES) |
18427 BIT(NL80211_STA_INFO_TX_FAILED);
18428#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018429
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018430 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018431
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018432 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18433 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018434 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18435 &sinfo->txrate, sizeof(sinfo->txrate));
18436
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018437 if (rate_flags & eHAL_TX_RATE_LEGACY)
18438 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18439 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18440 sinfo->rx_packets);
18441 else
18442 hddLog(LOG1,
18443 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18444 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18445 sinfo->tx_packets, sinfo->rx_packets);
18446
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018447 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18448 TRACE_CODE_HDD_CFG80211_GET_STA,
18449 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018450 EXIT();
18451 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018452}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18454static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18455 const u8* mac, struct station_info *sinfo)
18456#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018457static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18458 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018459#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018460{
18461 int ret;
18462
18463 vos_ssr_protect(__func__);
18464 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18465 vos_ssr_unprotect(__func__);
18466
18467 return ret;
18468}
18469
18470static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018471 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018472{
18473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018474 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018475 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018476 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018477
Jeff Johnsone7245742012-09-05 17:12:55 -070018478 ENTER();
18479
Jeff Johnson295189b2012-06-20 16:38:30 -070018480 if (NULL == pAdapter)
18481 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018483 return -ENODEV;
18484 }
18485
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18487 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18488 pAdapter->sessionId, timeout));
18489
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018490 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018491 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018492 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018493 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018494 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018495 }
18496
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018497 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18498 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18499 (pHddCtx->cfg_ini->fhostArpOffload) &&
18500 (eConnectionState_Associated ==
18501 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18502 {
Amar Singhald53568e2013-09-26 11:03:45 -070018503
18504 hddLog(VOS_TRACE_LEVEL_INFO,
18505 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018506 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018507 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18508 {
18509 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018510 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018511 __func__, vos_status);
18512 }
18513 }
18514
Jeff Johnson295189b2012-06-20 16:38:30 -070018515 /**The get power cmd from the supplicant gets updated by the nl only
18516 *on successful execution of the function call
18517 *we are oppositely mapped w.r.t mode in the driver
18518 **/
18519 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18520
18521 if (VOS_STATUS_E_FAILURE == vos_status)
18522 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18524 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018525 return -EINVAL;
18526 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018527 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018528 return 0;
18529}
18530
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018531static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18532 struct net_device *dev, bool mode, int timeout)
18533{
18534 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018535
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018536 vos_ssr_protect(__func__);
18537 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18538 vos_ssr_unprotect(__func__);
18539
18540 return ret;
18541}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018542
Jeff Johnson295189b2012-06-20 16:38:30 -070018543#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018544static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18545 struct net_device *netdev,
18546 u8 key_index)
18547{
18548 ENTER();
18549 return 0;
18550}
18551
Jeff Johnson295189b2012-06-20 16:38:30 -070018552static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018553 struct net_device *netdev,
18554 u8 key_index)
18555{
18556 int ret;
18557 vos_ssr_protect(__func__);
18558 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18559 vos_ssr_unprotect(__func__);
18560 return ret;
18561}
18562#endif //LINUX_VERSION_CODE
18563
18564#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18565static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18566 struct net_device *dev,
18567 struct ieee80211_txq_params *params)
18568{
18569 ENTER();
18570 return 0;
18571}
18572#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18573static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18574 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018575{
Jeff Johnsone7245742012-09-05 17:12:55 -070018576 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018577 return 0;
18578}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018579#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018580
18581#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18582static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018583 struct net_device *dev,
18584 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018585{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018586 int ret;
18587
18588 vos_ssr_protect(__func__);
18589 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18590 vos_ssr_unprotect(__func__);
18591 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018592}
18593#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18594static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18595 struct ieee80211_txq_params *params)
18596{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018597 int ret;
18598
18599 vos_ssr_protect(__func__);
18600 ret = __wlan_hdd_set_txq_params(wiphy, params);
18601 vos_ssr_unprotect(__func__);
18602 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018603}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018604#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018605
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018606static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018607 struct net_device *dev,
18608 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018609{
18610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018611 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018612 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018613 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018614 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018615 v_CONTEXT_t pVosContext = NULL;
18616 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018617
Jeff Johnsone7245742012-09-05 17:12:55 -070018618 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018619
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018620 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018621 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018623 return -EINVAL;
18624 }
18625
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018626 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18627 TRACE_CODE_HDD_CFG80211_DEL_STA,
18628 pAdapter->sessionId, pAdapter->device_mode));
18629
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018630 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18631 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018632 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018633 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018634 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018635 }
18636
Jeff Johnson295189b2012-06-20 16:38:30 -070018637 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018638 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018639 )
18640 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018641 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18642 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18643 if(pSapCtx == NULL){
18644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18645 FL("psapCtx is NULL"));
18646 return -ENOENT;
18647 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018648 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18649 {
18650 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18651 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18652 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18653 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018654 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018655 {
18656 v_U16_t i;
18657 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18658 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018659 if ((pSapCtx->aStaInfo[i].isUsed) &&
18660 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018661 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018662 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018663 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018664 ETHER_ADDR_LEN);
18665
Jeff Johnson295189b2012-06-20 16:38:30 -070018666 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018667 "%s: Delete STA with MAC::"
18668 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018669 __func__,
18670 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18671 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018672 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018673 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018674 }
18675 }
18676 }
18677 else
18678 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018679
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018680 vos_status = hdd_softap_GetStaId(pAdapter,
18681 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018682 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18683 {
18684 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018685 "%s: Skip this DEL STA as this is not used::"
18686 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018687 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018688 return -ENOENT;
18689 }
18690
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018691 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018692 {
18693 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018694 "%s: Skip this DEL STA as deauth is in progress::"
18695 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018696 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018697 return -ENOENT;
18698 }
18699
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018700 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018701
Jeff Johnson295189b2012-06-20 16:38:30 -070018702 hddLog(VOS_TRACE_LEVEL_INFO,
18703 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018704 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018705 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018706 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018707
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018708 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018709 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18710 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018711 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018712 hddLog(VOS_TRACE_LEVEL_INFO,
18713 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018714 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018715 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018716 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018717 return -ENOENT;
18718 }
18719
Jeff Johnson295189b2012-06-20 16:38:30 -070018720 }
18721 }
18722
18723 EXIT();
18724
18725 return 0;
18726}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018727
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018728#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018729int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018730 struct net_device *dev,
18731 struct station_del_parameters *param)
18732#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018733#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018734int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018735 struct net_device *dev, const u8 *mac)
18736#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018737int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018738 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018739#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018740#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018741{
18742 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018743 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018744
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018745 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018746
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018747#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018748 if (NULL == param) {
18749 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018750 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018751 return -EINVAL;
18752 }
18753
18754 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18755 param->subtype, &delStaParams);
18756
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018757#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018758 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018759 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018760#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018761 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18762
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018763 vos_ssr_unprotect(__func__);
18764
18765 return ret;
18766}
18767
18768static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018769 struct net_device *dev,
18770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18771 const u8 *mac,
18772#else
18773 u8 *mac,
18774#endif
18775 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018776{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018777 hdd_adapter_t *pAdapter;
18778 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018779 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018780#ifdef FEATURE_WLAN_TDLS
18781 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018782
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018783 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018784
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018785 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18786 if (NULL == pAdapter)
18787 {
18788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18789 "%s: Adapter is NULL",__func__);
18790 return -EINVAL;
18791 }
18792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18793 status = wlan_hdd_validate_context(pHddCtx);
18794 if (0 != status)
18795 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018796 return status;
18797 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018798
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018799 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18800 TRACE_CODE_HDD_CFG80211_ADD_STA,
18801 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018802 mask = params->sta_flags_mask;
18803
18804 set = params->sta_flags_set;
18805
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018807 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18808 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018809
18810 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18811 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018812 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018813 }
18814 }
18815#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018816 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018817 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018818}
18819
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18821static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18822 struct net_device *dev, const u8 *mac,
18823 struct station_parameters *params)
18824#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018825static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18826 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018827#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018828{
18829 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018830
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018831 vos_ssr_protect(__func__);
18832 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18833 vos_ssr_unprotect(__func__);
18834
18835 return ret;
18836}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018837#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018838
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018839static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018840 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018841{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18843 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018844 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018845 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018846 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018847 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018848
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018849 ENTER();
18850
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018851 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018852 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018855 return -EINVAL;
18856 }
18857
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018858 if (!pmksa) {
18859 hddLog(LOGE, FL("pmksa is NULL"));
18860 return -EINVAL;
18861 }
18862
18863 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018864 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018865 pmksa->bssid, pmksa->pmkid);
18866 return -EINVAL;
18867 }
18868
18869 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18870 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18871
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18873 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018874 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018875 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018876 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018877 }
18878
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018879 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018880 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18881
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018882 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18883 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018884
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018885 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018886 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018887 &pmk_id, 1, FALSE);
18888
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018889 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18890 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18891 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018892
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018893 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018894 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018895}
18896
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018897static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18898 struct cfg80211_pmksa *pmksa)
18899{
18900 int ret;
18901
18902 vos_ssr_protect(__func__);
18903 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18904 vos_ssr_unprotect(__func__);
18905
18906 return ret;
18907}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018908
Wilson Yang6507c4e2013-10-01 20:11:19 -070018909
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018910static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018911 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018912{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018913 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18914 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018915 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018916 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018918 ENTER();
18919
Wilson Yang6507c4e2013-10-01 20:11:19 -070018920 /* Validate pAdapter */
18921 if (NULL == pAdapter)
18922 {
18923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18924 return -EINVAL;
18925 }
18926
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018927 if (!pmksa) {
18928 hddLog(LOGE, FL("pmksa is NULL"));
18929 return -EINVAL;
18930 }
18931
18932 if (!pmksa->bssid) {
18933 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18934 return -EINVAL;
18935 }
18936
Kiet Lam98c46a12014-10-31 15:34:57 -070018937 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18938 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18939
Wilson Yang6507c4e2013-10-01 20:11:19 -070018940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18941 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018942 if (0 != status)
18943 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018944 return status;
18945 }
18946
18947 /*Retrieve halHandle*/
18948 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18949
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18951 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18952 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018953 /* Delete the PMKID CSR cache */
18954 if (eHAL_STATUS_SUCCESS !=
18955 sme_RoamDelPMKIDfromCache(halHandle,
18956 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18957 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18958 MAC_ADDR_ARRAY(pmksa->bssid));
18959 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018960 }
18961
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018962 EXIT();
18963 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018964}
18965
Wilson Yang6507c4e2013-10-01 20:11:19 -070018966
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018967static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18968 struct cfg80211_pmksa *pmksa)
18969{
18970 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018971
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018972 vos_ssr_protect(__func__);
18973 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18974 vos_ssr_unprotect(__func__);
18975
18976 return ret;
18977
18978}
18979
18980static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018981{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18983 tHalHandle halHandle;
18984 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018985 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018986
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018987 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018988
18989 /* Validate pAdapter */
18990 if (NULL == pAdapter)
18991 {
18992 hddLog(VOS_TRACE_LEVEL_ERROR,
18993 "%s: Invalid Adapter" ,__func__);
18994 return -EINVAL;
18995 }
18996
18997 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18998 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018999 if (0 != status)
19000 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019001 return status;
19002 }
19003
19004 /*Retrieve halHandle*/
19005 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19006
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019007 /* Flush the PMKID cache in CSR */
19008 if (eHAL_STATUS_SUCCESS !=
19009 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19011 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019012 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019013 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019014 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019015}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019016
19017static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19018{
19019 int ret;
19020
19021 vos_ssr_protect(__func__);
19022 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19023 vos_ssr_unprotect(__func__);
19024
19025 return ret;
19026}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019027#endif
19028
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019029#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019030static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19031 struct net_device *dev,
19032 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019033{
19034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19035 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019036 hdd_context_t *pHddCtx;
19037 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019038
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019039 ENTER();
19040
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019041 if (NULL == pAdapter)
19042 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019044 return -ENODEV;
19045 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019046 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19047 ret = wlan_hdd_validate_context(pHddCtx);
19048 if (0 != ret)
19049 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019050 return ret;
19051 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019052 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019053 if (NULL == pHddStaCtx)
19054 {
19055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19056 return -EINVAL;
19057 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019058
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019059 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19060 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19061 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019062 // Added for debug on reception of Re-assoc Req.
19063 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19064 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019065 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019066 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019067 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019068 }
19069
19070#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019071 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019072 ftie->ie_len);
19073#endif
19074
19075 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019076 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19077 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019078 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019079
19080 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019081 return 0;
19082}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019083
19084static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19085 struct net_device *dev,
19086 struct cfg80211_update_ft_ies_params *ftie)
19087{
19088 int ret;
19089
19090 vos_ssr_protect(__func__);
19091 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19092 vos_ssr_unprotect(__func__);
19093
19094 return ret;
19095}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019096#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019097
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019098#ifdef FEATURE_WLAN_SCAN_PNO
19099
19100void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19101 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19102{
19103 int ret;
19104 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19105 hdd_context_t *pHddCtx;
19106
Nirav Shah80830bf2013-12-31 16:35:12 +053019107 ENTER();
19108
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019109 if (NULL == pAdapter)
19110 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019112 "%s: HDD adapter is Null", __func__);
19113 return ;
19114 }
19115
19116 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19117 if (NULL == pHddCtx)
19118 {
19119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19120 "%s: HDD context is Null!!!", __func__);
19121 return ;
19122 }
19123
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019124 spin_lock(&pHddCtx->schedScan_lock);
19125 if (TRUE == pHddCtx->isWiphySuspended)
19126 {
19127 pHddCtx->isSchedScanUpdatePending = TRUE;
19128 spin_unlock(&pHddCtx->schedScan_lock);
19129 hddLog(VOS_TRACE_LEVEL_INFO,
19130 "%s: Update cfg80211 scan database after it resume", __func__);
19131 return ;
19132 }
19133 spin_unlock(&pHddCtx->schedScan_lock);
19134
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019135 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19136
19137 if (0 > ret)
19138 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019139 else
19140 {
19141 /* Acquire wakelock to handle the case where APP's tries to suspend
19142 * immediatly after the driver gets connect request(i.e after pno)
19143 * from supplicant, this result in app's is suspending and not able
19144 * to process the connect request to AP */
19145 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19146 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019147 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19149 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019150}
19151
19152/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019153 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019154 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019155 */
19156static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19157{
19158 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19159 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019160 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019161 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19162 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019163
19164 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19165 {
19166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19167 "%s: PNO is allowed only in STA interface", __func__);
19168 return eHAL_STATUS_FAILURE;
19169 }
19170
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019171 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19172
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019173 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019174 * active sessions. PNO is allowed only in case when sap session
19175 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019176 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019177 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19178 {
19179 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019180 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019181
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019182 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19183 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19184 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19185 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019186 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19187 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019188 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019189 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019190 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019191 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019192 }
19193 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19194 pAdapterNode = pNext;
19195 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019196 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019197}
19198
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019199void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19200{
19201 hdd_adapter_t *pAdapter = callbackContext;
19202 hdd_context_t *pHddCtx;
19203
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019204 ENTER();
19205
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019206 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19207 {
19208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19209 FL("Invalid adapter or adapter has invalid magic"));
19210 return;
19211 }
19212
19213 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19214 if (0 != wlan_hdd_validate_context(pHddCtx))
19215 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019216 return;
19217 }
19218
c_hpothub53c45d2014-08-18 16:53:14 +053019219 if (VOS_STATUS_SUCCESS != status)
19220 {
19221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019222 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019223 pHddCtx->isPnoEnable = FALSE;
19224 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019225
19226 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19227 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019228 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019229}
19230
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19232 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19233/**
19234 * hdd_config_sched_scan_plan() - configures the sched scan plans
19235 * from the framework.
19236 * @pno_req: pointer to PNO scan request
19237 * @request: pointer to scan request from framework
19238 *
19239 * Return: None
19240 */
19241static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19242 struct cfg80211_sched_scan_request *request,
19243 hdd_context_t *hdd_ctx)
19244{
19245 v_U32_t i = 0;
19246
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019247 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019248 for (i = 0; i < request->n_scan_plans; i++)
19249 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019250 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19251 request->scan_plans[i].iterations;
19252 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19253 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019254 }
19255}
19256#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019257static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019258 struct cfg80211_sched_scan_request *request,
19259 hdd_context_t *hdd_ctx)
19260{
19261 v_U32_t i, temp_int;
19262 /* Driver gets only one time interval which is hardcoded in
19263 * supplicant for 10000ms. Taking power consumption into account 6
19264 * timers will be used, Timervalue is increased exponentially
19265 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19266 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19267 * If it is set to 0 only one timer will be used and PNO scan cycle
19268 * will be repeated after each interval specified by supplicant
19269 * till PNO is disabled.
19270 */
19271 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019272 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019273 HDD_PNO_SCAN_TIMERS_SET_ONE;
19274 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019275 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019276 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19277
19278 temp_int = (request->interval)/1000;
19279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19280 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19281 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019282 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019283 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019284 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019285 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019286 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019287 temp_int *= 2;
19288 }
19289 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019290 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019291}
19292#endif
19293
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019294/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019295 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19296 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019297 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019298static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019299 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19300{
19301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019302 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019303 hdd_context_t *pHddCtx;
19304 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019305 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019306 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19307 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019308 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19309 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019310 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019311 hdd_config_t *pConfig = NULL;
19312 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019313
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019314 ENTER();
19315
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019316 if (NULL == pAdapter)
19317 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019319 "%s: HDD adapter is Null", __func__);
19320 return -ENODEV;
19321 }
19322
19323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019324 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019325
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019326 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019327 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019328 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019329 }
19330
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019331 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019332 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19333 if (NULL == hHal)
19334 {
19335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19336 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019337 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019338 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019339 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19340 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19341 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019342 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019343 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019344 {
19345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19346 "%s: aborting the existing scan is unsuccessfull", __func__);
19347 return -EBUSY;
19348 }
19349
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019350 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019351 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019353 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019354 return -EBUSY;
19355 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019356
c_hpothu37f21312014-04-09 21:49:54 +053019357 if (TRUE == pHddCtx->isPnoEnable)
19358 {
19359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19360 FL("already PNO is enabled"));
19361 return -EBUSY;
19362 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019363
19364 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19365 {
19366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19367 "%s: abort ROC failed ", __func__);
19368 return -EBUSY;
19369 }
19370
c_hpothu37f21312014-04-09 21:49:54 +053019371 pHddCtx->isPnoEnable = TRUE;
19372
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019373 pnoRequest.enable = 1; /*Enable PNO */
19374 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019375
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019376 if (( !pnoRequest.ucNetworksCount ) ||
19377 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019378 {
19379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019380 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019381 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019382 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019383 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019384 goto error;
19385 }
19386
19387 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19388 {
19389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019390 "%s: Incorrect number of channels %d",
19391 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019392 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019393 goto error;
19394 }
19395
19396 /* Framework provides one set of channels(all)
19397 * common for all saved profile */
19398 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19399 channels_allowed, &num_channels_allowed))
19400 {
19401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19402 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019403 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019404 goto error;
19405 }
19406 /* Checking each channel against allowed channel list */
19407 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019408 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019409 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019410 char chList [(request->n_channels*5)+1];
19411 int len;
19412 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019413 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019414 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019415 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019416 if (request->channels[i]->hw_value == channels_allowed[indx])
19417 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019418 if ((!pConfig->enableDFSPnoChnlScan) &&
19419 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19420 {
19421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19422 "%s : Dropping DFS channel : %d",
19423 __func__,channels_allowed[indx]);
19424 num_ignore_dfs_ch++;
19425 break;
19426 }
19427
Nirav Shah80830bf2013-12-31 16:35:12 +053019428 valid_ch[num_ch++] = request->channels[i]->hw_value;
19429 len += snprintf(chList+len, 5, "%d ",
19430 request->channels[i]->hw_value);
19431 break ;
19432 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019433 }
19434 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019435 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019436
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019437 /*If all channels are DFS and dropped, then ignore the PNO request*/
19438 if (num_ignore_dfs_ch == request->n_channels)
19439 {
19440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19441 "%s : All requested channels are DFS channels", __func__);
19442 ret = -EINVAL;
19443 goto error;
19444 }
19445 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019446
19447 pnoRequest.aNetworks =
19448 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19449 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019450 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019451 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19452 FL("failed to allocate memory aNetworks %u"),
19453 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19454 goto error;
19455 }
19456 vos_mem_zero(pnoRequest.aNetworks,
19457 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19458
19459 /* Filling per profile params */
19460 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19461 {
19462 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019463 request->match_sets[i].ssid.ssid_len;
19464
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019465 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19466 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019467 {
19468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019469 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019470 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019471 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019472 goto error;
19473 }
19474
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019475 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019476 request->match_sets[i].ssid.ssid,
19477 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19479 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019480 i, pnoRequest.aNetworks[i].ssId.ssId);
19481 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19482 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19483 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019484
19485 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019486 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19487 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019488
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019489 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019490 }
19491
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019492 for (i = 0; i < request->n_ssids; i++)
19493 {
19494 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019495 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019496 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019497 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019498 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019499 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019500 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019501 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019502 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019503 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019504 break;
19505 }
19506 j++;
19507 }
19508 }
19509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19510 "Number of hidden networks being Configured = %d",
19511 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019513 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019514
19515 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19516 if (pnoRequest.p24GProbeTemplate == NULL)
19517 {
19518 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19519 FL("failed to allocate memory p24GProbeTemplate %u"),
19520 SIR_PNO_MAX_PB_REQ_SIZE);
19521 goto error;
19522 }
19523
19524 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19525 if (pnoRequest.p5GProbeTemplate == NULL)
19526 {
19527 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19528 FL("failed to allocate memory p5GProbeTemplate %u"),
19529 SIR_PNO_MAX_PB_REQ_SIZE);
19530 goto error;
19531 }
19532
19533 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19534 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19535
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019536 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19537 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019538 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019539 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19540 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19541 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019542
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019543 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19544 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19545 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019546 }
19547
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019548 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019549
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019550 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019551
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019552 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019553 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19554 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019555 pAdapter->pno_req_status = 0;
19556
Nirav Shah80830bf2013-12-31 16:35:12 +053019557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19558 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019559 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19560 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019561
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019562 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019563 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019564 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19565 if (eHAL_STATUS_SUCCESS != status)
19566 {
19567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019568 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019569 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019570 goto error;
19571 }
19572
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019573 ret = wait_for_completion_timeout(
19574 &pAdapter->pno_comp_var,
19575 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19576 if (0 >= ret)
19577 {
19578 // Did not receive the response for PNO enable in time.
19579 // Assuming the PNO enable was success.
19580 // Returning error from here, because we timeout, results
19581 // in side effect of Wifi (Wifi Setting) not to work.
19582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19583 FL("Timed out waiting for PNO to be Enabled"));
19584 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019585 }
19586
19587 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019588 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019589
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019590error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19592 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019593 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019594 if (pnoRequest.aNetworks)
19595 vos_mem_free(pnoRequest.aNetworks);
19596 if (pnoRequest.p24GProbeTemplate)
19597 vos_mem_free(pnoRequest.p24GProbeTemplate);
19598 if (pnoRequest.p5GProbeTemplate)
19599 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019600
19601 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019602 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019603}
19604
19605/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019606 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19607 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019608 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019609static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19610 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19611{
19612 int ret;
19613
19614 vos_ssr_protect(__func__);
19615 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19616 vos_ssr_unprotect(__func__);
19617
19618 return ret;
19619}
19620
19621/*
19622 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19623 * Function to disable PNO
19624 */
19625static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019626 struct net_device *dev)
19627{
19628 eHalStatus status = eHAL_STATUS_FAILURE;
19629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19630 hdd_context_t *pHddCtx;
19631 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019632 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019633 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019634
19635 ENTER();
19636
19637 if (NULL == pAdapter)
19638 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019640 "%s: HDD adapter is Null", __func__);
19641 return -ENODEV;
19642 }
19643
19644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019645
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019646 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019647 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019649 "%s: HDD context is Null", __func__);
19650 return -ENODEV;
19651 }
19652
19653 /* The return 0 is intentional when isLogpInProgress and
19654 * isLoadUnloadInProgress. We did observe a crash due to a return of
19655 * failure in sched_scan_stop , especially for a case where the unload
19656 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19657 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19658 * success. If it returns a failure , then its next invocation due to the
19659 * clean up of the second interface will have the dev pointer corresponding
19660 * to the first one leading to a crash.
19661 */
19662 if (pHddCtx->isLogpInProgress)
19663 {
19664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19665 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019666 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019667 return ret;
19668 }
19669
Mihir Shete18156292014-03-11 15:38:30 +053019670 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019671 {
19672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19673 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19674 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019675 }
19676
19677 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19678 if (NULL == hHal)
19679 {
19680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19681 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019682 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019683 }
19684
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019685 pnoRequest.enable = 0; /* Disable PNO */
19686 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019687
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19689 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19690 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019691
19692 INIT_COMPLETION(pAdapter->pno_comp_var);
19693 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19694 pnoRequest.callbackContext = pAdapter;
19695 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019696 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019697 pAdapter->sessionId,
19698 NULL, pAdapter);
19699 if (eHAL_STATUS_SUCCESS != status)
19700 {
19701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19702 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019703 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019704 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019705 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019706 ret = wait_for_completion_timeout(
19707 &pAdapter->pno_comp_var,
19708 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19709 if (0 >= ret)
19710 {
19711 // Did not receive the response for PNO disable in time.
19712 // Assuming the PNO disable was success.
19713 // Returning error from here, because we timeout, results
19714 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019716 FL("Timed out waiting for PNO to be disabled"));
19717 ret = 0;
19718 }
19719
19720 ret = pAdapter->pno_req_status;
19721 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019722
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019723error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019725 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019726
19727 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019728 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019729}
19730
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019731/*
19732 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19733 * NL interface to disable PNO
19734 */
19735static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19736 struct net_device *dev)
19737{
19738 int ret;
19739
19740 vos_ssr_protect(__func__);
19741 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19742 vos_ssr_unprotect(__func__);
19743
19744 return ret;
19745}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019746#endif /*FEATURE_WLAN_SCAN_PNO*/
19747
19748
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019749#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019750#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019751static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19752 struct net_device *dev,
19753 u8 *peer, u8 action_code,
19754 u8 dialog_token,
19755 u16 status_code, u32 peer_capability,
19756 const u8 *buf, size_t len)
19757#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19759 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019760static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19761 struct net_device *dev,
19762 const u8 *peer, u8 action_code,
19763 u8 dialog_token, u16 status_code,
19764 u32 peer_capability, bool initiator,
19765 const u8 *buf, size_t len)
19766#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19767static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19768 struct net_device *dev,
19769 const u8 *peer, u8 action_code,
19770 u8 dialog_token, u16 status_code,
19771 u32 peer_capability, const u8 *buf,
19772 size_t len)
19773#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19774static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19775 struct net_device *dev,
19776 u8 *peer, u8 action_code,
19777 u8 dialog_token,
19778 u16 status_code, u32 peer_capability,
19779 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019780#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019781static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19782 struct net_device *dev,
19783 u8 *peer, u8 action_code,
19784 u8 dialog_token,
19785 u16 status_code, const u8 *buf,
19786 size_t len)
19787#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019788#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019789{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019790 hdd_adapter_t *pAdapter;
19791 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019792 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019793 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019794 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019795 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019796 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019797 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019798#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019799 u32 peer_capability = 0;
19800#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019801 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019802 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019803 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019804
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019805 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19806 if (NULL == pAdapter)
19807 {
19808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19809 "%s: Adapter is NULL",__func__);
19810 return -EINVAL;
19811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19813 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19814 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019815
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019816 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019817 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019820 "Invalid arguments");
19821 return -EINVAL;
19822 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019823
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019824 if (pHddCtx->isLogpInProgress)
19825 {
19826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19827 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019828 wlan_hdd_tdls_set_link_status(pAdapter,
19829 peer,
19830 eTDLS_LINK_IDLE,
19831 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019832 return -EBUSY;
19833 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019834
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019835 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19836 {
19837 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19838 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19839 return -EAGAIN;
19840 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019841
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019842 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19843 if (!pHddTdlsCtx) {
19844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19845 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053019846 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019847 }
19848
Hoonki Lee27511902013-03-14 18:19:06 -070019849 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019850 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019852 "%s: TDLS mode is disabled OR not enabled in FW."
19853 MAC_ADDRESS_STR " action %d declined.",
19854 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019855 return -ENOTSUPP;
19856 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019857
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019858 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19859
19860 if( NULL == pHddStaCtx )
19861 {
19862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19863 "%s: HDD station context NULL ",__func__);
19864 return -EINVAL;
19865 }
19866
19867 /* STA should be connected and authenticated
19868 * before sending any TDLS frames
19869 */
19870 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19871 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19872 {
19873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19874 "STA is not connected or unauthenticated. "
19875 "connState %u, uIsAuthenticated %u",
19876 pHddStaCtx->conn_info.connState,
19877 pHddStaCtx->conn_info.uIsAuthenticated);
19878 return -EAGAIN;
19879 }
19880
Hoonki Lee27511902013-03-14 18:19:06 -070019881 /* other than teardown frame, other mgmt frames are not sent if disabled */
19882 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19883 {
19884 /* if tdls_mode is disabled to respond to peer's request */
19885 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19886 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019888 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019889 " TDLS mode is disabled. action %d declined.",
19890 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019891
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019892 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019893 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019894
19895 if (vos_max_concurrent_connections_reached())
19896 {
19897 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19898 return -EINVAL;
19899 }
Hoonki Lee27511902013-03-14 18:19:06 -070019900 }
19901
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019902 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19903 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019904 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019905 {
19906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019907 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019908 " TDLS setup is ongoing. action %d declined.",
19909 __func__, MAC_ADDR_ARRAY(peer), action_code);
19910 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019911 }
19912 }
19913
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019914 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19915 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019916 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019917 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19918 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019919 {
19920 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19921 we return error code at 'add_station()'. Hence we have this
19922 check again in addtion to add_station().
19923 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019924 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019925 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19927 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019928 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19929 __func__, MAC_ADDR_ARRAY(peer), action_code,
19930 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019931 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019932 }
19933 else
19934 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019935 /* maximum reached. tweak to send error code to peer and return
19936 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019937 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19939 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019940 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19941 __func__, MAC_ADDR_ARRAY(peer), status_code,
19942 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019943 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019944 /* fall through to send setup resp with failure status
19945 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019946 }
19947 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019948 else
19949 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019950 mutex_lock(&pHddCtx->tdls_lock);
19951 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019952 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019953 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019954 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019956 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19957 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019958 return -EPERM;
19959 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019960 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019961 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019962 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019963
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019965 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019966 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19967 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019968
Hoonki Leea34dd892013-02-05 22:56:02 -080019969 /*Except teardown responder will not be used so just make 0*/
19970 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019971 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019972 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019973
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019974 mutex_lock(&pHddCtx->tdls_lock);
19975 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019976
19977 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19978 responder = pTdlsPeer->is_responder;
19979 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019980 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019982 "%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 -070019983 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19984 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019985 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019986 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019987 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019988 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019989 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019990
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019991 /* Discard TDLS setup if peer is removed by user app */
19992 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19993 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19994 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19995 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19996
19997 mutex_lock(&pHddCtx->tdls_lock);
19998 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19999 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20000 mutex_unlock(&pHddCtx->tdls_lock);
20001 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20002 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20003 MAC_ADDR_ARRAY(peer), action_code);
20004 return -EINVAL;
20005 }
20006 mutex_unlock(&pHddCtx->tdls_lock);
20007 }
20008
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020009 /* For explicit trigger of DIS_REQ come out of BMPS for
20010 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020011 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020012 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020013 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20014 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020015 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020016 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020018 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20019 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020020 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20021 if (status != VOS_STATUS_SUCCESS) {
20022 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020023 } else {
20024 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020025 }
Hoonki Lee14621352013-04-16 17:51:19 -070020026 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020027 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020028 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20030 }
20031 }
Hoonki Lee14621352013-04-16 17:51:19 -070020032 }
20033
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020034 /* make sure doesn't call send_mgmt() while it is pending */
20035 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20036 {
20037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020038 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020039 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020040 ret = -EBUSY;
20041 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020042 }
20043
20044 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020045 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20046
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020047 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20048 pAdapter->sessionId, peer, action_code, dialog_token,
20049 status_code, peer_capability, (tANI_U8 *)buf, len,
20050 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020051
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020052 if (VOS_STATUS_SUCCESS != status)
20053 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20055 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020056 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020057 ret = -EINVAL;
20058 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020059 }
20060
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20062 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20063 WAIT_TIME_TDLS_MGMT);
20064
Hoonki Leed37cbb32013-04-20 00:31:14 -070020065 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20066 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20067
20068 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020069 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020071 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020072 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020073 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020074
20075 if (pHddCtx->isLogpInProgress)
20076 {
20077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20078 "%s: LOGP in Progress. Ignore!!!", __func__);
20079 return -EAGAIN;
20080 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020081 if (rc <= 0)
20082 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20083 WLAN_LOG_INDICATOR_HOST_DRIVER,
20084 WLAN_LOG_REASON_HDD_TIME_OUT,
20085 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020086
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020087 ret = -EINVAL;
20088 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020089 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020090 else
20091 {
20092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20093 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20094 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20095 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020096
Gopichand Nakkala05922802013-03-14 12:23:19 -070020097 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020098 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020099 ret = max_sta_failed;
20100 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020101 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020102
Hoonki Leea34dd892013-02-05 22:56:02 -080020103 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20104 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020105 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20107 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020108 }
20109 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20110 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020111 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20113 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020114 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020115
20116 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020117
20118tx_failed:
20119 /* add_station will be called before sending TDLS_SETUP_REQ and
20120 * TDLS_SETUP_RSP and as part of add_station driver will enable
20121 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20122 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20123 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20124 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20125 */
20126
20127 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20128 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20129 wlan_hdd_tdls_check_bmps(pAdapter);
20130 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020131}
20132
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020133#if TDLS_MGMT_VERSION2
20134static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20135 u8 *peer, u8 action_code, u8 dialog_token,
20136 u16 status_code, u32 peer_capability,
20137 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020138#else /* TDLS_MGMT_VERSION2 */
20139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20140static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20141 struct net_device *dev,
20142 const u8 *peer, u8 action_code,
20143 u8 dialog_token, u16 status_code,
20144 u32 peer_capability, bool initiator,
20145 const u8 *buf, size_t len)
20146#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20147static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20148 struct net_device *dev,
20149 const u8 *peer, u8 action_code,
20150 u8 dialog_token, u16 status_code,
20151 u32 peer_capability, const u8 *buf,
20152 size_t len)
20153#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20154static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20155 struct net_device *dev,
20156 u8 *peer, u8 action_code,
20157 u8 dialog_token,
20158 u16 status_code, u32 peer_capability,
20159 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020160#else
20161static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20162 u8 *peer, u8 action_code, u8 dialog_token,
20163 u16 status_code, const u8 *buf, size_t len)
20164#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020165#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020166{
20167 int ret;
20168
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020169 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020170#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020171 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20172 dialog_token, status_code,
20173 peer_capability, buf, len);
20174#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020175#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20176 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020177 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20178 dialog_token, status_code,
20179 peer_capability, initiator,
20180 buf, len);
20181#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20182 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20183 dialog_token, status_code,
20184 peer_capability, buf, len);
20185#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20186 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20187 dialog_token, status_code,
20188 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020189#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020190 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20191 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020192#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020193#endif
20194 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020195
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020196 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020197}
Atul Mittal115287b2014-07-08 13:26:33 +053020198
20199int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020200#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20201 const u8 *peer,
20202#else
Atul Mittal115287b2014-07-08 13:26:33 +053020203 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020204#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020205 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020206 cfg80211_exttdls_callback callback)
20207{
20208
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020209 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020210 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020211 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20213 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20214 __func__, MAC_ADDR_ARRAY(peer));
20215
20216 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20217 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20218
20219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020220 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20221 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20222 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020223 return -ENOTSUPP;
20224 }
20225
20226 /* To cater the requirement of establishing the TDLS link
20227 * irrespective of the data traffic , get an entry of TDLS peer.
20228 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020229 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020230 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20231 if (pTdlsPeer == NULL) {
20232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20233 "%s: peer " MAC_ADDRESS_STR " not existing",
20234 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020235 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020236 return -EINVAL;
20237 }
20238
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020239 /* check FW TDLS Off Channel capability */
20240 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020241 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020242 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020243 {
20244 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20245 pTdlsPeer->peerParams.global_operating_class =
20246 tdls_peer_params->global_operating_class;
20247 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20248 pTdlsPeer->peerParams.min_bandwidth_kbps =
20249 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020250 /* check configured channel is valid, non dfs and
20251 * not current operating channel */
20252 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20253 tdls_peer_params->channel)) &&
20254 (pHddStaCtx) &&
20255 (tdls_peer_params->channel !=
20256 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020257 {
20258 pTdlsPeer->isOffChannelConfigured = TRUE;
20259 }
20260 else
20261 {
20262 pTdlsPeer->isOffChannelConfigured = FALSE;
20263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20264 "%s: Configured Tdls Off Channel is not valid", __func__);
20265
20266 }
20267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020268 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20269 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020270 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020271 pTdlsPeer->isOffChannelConfigured,
20272 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020273 }
20274 else
20275 {
20276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020277 "%s: TDLS off channel FW capability %d, "
20278 "host capab %d or Invalid TDLS Peer Params", __func__,
20279 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20280 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020281 }
20282
Atul Mittal115287b2014-07-08 13:26:33 +053020283 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20284
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020285 mutex_unlock(&pHddCtx->tdls_lock);
20286
Atul Mittal115287b2014-07-08 13:26:33 +053020287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20288 " %s TDLS Add Force Peer Failed",
20289 __func__);
20290 return -EINVAL;
20291 }
20292 /*EXT TDLS*/
20293
20294 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020295 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20297 " %s TDLS set callback Failed",
20298 __func__);
20299 return -EINVAL;
20300 }
20301
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020302 mutex_unlock(&pHddCtx->tdls_lock);
20303
Atul Mittal115287b2014-07-08 13:26:33 +053020304 return(0);
20305
20306}
20307
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020308int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20309#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20310 const u8 *peer
20311#else
20312 u8 *peer
20313#endif
20314)
Atul Mittal115287b2014-07-08 13:26:33 +053020315{
20316
20317 hddTdlsPeer_t *pTdlsPeer;
20318 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020319
Atul Mittal115287b2014-07-08 13:26:33 +053020320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20321 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20322 __func__, MAC_ADDR_ARRAY(peer));
20323
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020324 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20326 return -EINVAL;
20327 }
20328
Atul Mittal115287b2014-07-08 13:26:33 +053020329 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20330 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20331
20332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020333 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20334 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20335 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020336 return -ENOTSUPP;
20337 }
20338
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020339 mutex_lock(&pHddCtx->tdls_lock);
20340 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020341
20342 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020343 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020345 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020346 __func__, MAC_ADDR_ARRAY(peer));
20347 return -EINVAL;
20348 }
20349 else {
20350 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20351 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020352 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20353 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020354 /* if channel switch is configured, reset
20355 the channel for this peer */
20356 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20357 {
20358 pTdlsPeer->peerParams.channel = 0;
20359 pTdlsPeer->isOffChannelConfigured = FALSE;
20360 }
Atul Mittal115287b2014-07-08 13:26:33 +053020361 }
20362
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020363 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020364 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020365 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020366 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020367 }
Atul Mittal115287b2014-07-08 13:26:33 +053020368
20369 /*EXT TDLS*/
20370
20371 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020372 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20374 " %s TDLS set callback Failed",
20375 __func__);
20376 return -EINVAL;
20377 }
Atul Mittal115287b2014-07-08 13:26:33 +053020378
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020379 mutex_unlock(&pHddCtx->tdls_lock);
20380
20381 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020382}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020383static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020384#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20385 const u8 *peer,
20386#else
20387 u8 *peer,
20388#endif
20389 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020390{
20391 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020393 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020394 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020396 ENTER();
20397
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020398 if (!pAdapter) {
20399 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20400 return -EINVAL;
20401 }
20402
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20404 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20405 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020406 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020407 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020409 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020410 return -EINVAL;
20411 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020412
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020413 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020414 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020415 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020416 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020417 }
20418
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020419
20420 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020421 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020422 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020424 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20425 "Cannot process TDLS commands",
20426 pHddCtx->cfg_ini->fEnableTDLSSupport,
20427 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020428 return -ENOTSUPP;
20429 }
20430
20431 switch (oper) {
20432 case NL80211_TDLS_ENABLE_LINK:
20433 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020434 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020435 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020436 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20437 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020438 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020439 tANI_U16 numCurrTdlsPeers = 0;
20440 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020441 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020442 tSirMacAddr peerMac;
20443 int channel;
20444 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020445
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20447 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20448 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020449
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020450 mutex_lock(&pHddCtx->tdls_lock);
20451 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020452 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020453 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020454 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20456 " (oper %d) not exsting. ignored",
20457 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20458 return -EINVAL;
20459 }
20460
20461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20462 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20463 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20464 "NL80211_TDLS_ENABLE_LINK");
20465
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020466 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20467 {
20468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20469 MAC_ADDRESS_STR " failed",
20470 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020471 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020472 return -EINVAL;
20473 }
20474
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020475 /* before starting tdls connection, set tdls
20476 * off channel established status to default value */
20477 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020478
20479 mutex_unlock(&pHddCtx->tdls_lock);
20480
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020481 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020482 /* TDLS Off Channel, Disable tdls channel switch,
20483 when there are more than one tdls link */
20484 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020485 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020486 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020487 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020488 /* get connected peer and send disable tdls off chan */
20489 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020490 if ((connPeer) &&
20491 (connPeer->isOffChannelSupported == TRUE) &&
20492 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020493 {
20494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20495 "%s: More then one peer connected, Disable "
20496 "TDLS channel switch", __func__);
20497
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020498 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020499 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20500 channel = connPeer->peerParams.channel;
20501
20502 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020503
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020504 ret = sme_SendTdlsChanSwitchReq(
20505 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020506 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020507 peerMac,
20508 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020509 TDLS_OFF_CHANNEL_BW_OFFSET,
20510 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020511 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020512 hddLog(VOS_TRACE_LEVEL_ERROR,
20513 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020514 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020515 }
20516 else
20517 {
20518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20519 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020520 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020521 "isOffChannelConfigured %d",
20522 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020523 (connPeer ? (connPeer->isOffChannelSupported)
20524 : -1),
20525 (connPeer ? (connPeer->isOffChannelConfigured)
20526 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020527 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020528 }
20529 }
20530
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020531 mutex_lock(&pHddCtx->tdls_lock);
20532 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20533 if ( NULL == pTdlsPeer ) {
20534 mutex_unlock(&pHddCtx->tdls_lock);
20535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20536 "%s: " MAC_ADDRESS_STR
20537 " (oper %d) peer got freed in other context. ignored",
20538 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20539 return -EINVAL;
20540 }
20541 peer_status = pTdlsPeer->link_status;
20542 mutex_unlock(&pHddCtx->tdls_lock);
20543
20544 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020545 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020546 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020547
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020548 if (0 != wlan_hdd_tdls_get_link_establish_params(
20549 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020551 return -EINVAL;
20552 }
20553 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020554
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020555 ret = sme_SendTdlsLinkEstablishParams(
20556 WLAN_HDD_GET_HAL_CTX(pAdapter),
20557 pAdapter->sessionId, peer,
20558 &tdlsLinkEstablishParams);
20559 if (ret != VOS_STATUS_SUCCESS) {
20560 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20561 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020562 /* Send TDLS peer UAPSD capabilities to the firmware and
20563 * register with the TL on after the response for this operation
20564 * is received .
20565 */
20566 ret = wait_for_completion_interruptible_timeout(
20567 &pAdapter->tdls_link_establish_req_comp,
20568 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020569
20570 mutex_lock(&pHddCtx->tdls_lock);
20571 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20572 if ( NULL == pTdlsPeer ) {
20573 mutex_unlock(&pHddCtx->tdls_lock);
20574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20575 "%s %d: " MAC_ADDRESS_STR
20576 " (oper %d) peer got freed in other context. ignored",
20577 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20578 (int)oper);
20579 return -EINVAL;
20580 }
20581 peer_status = pTdlsPeer->link_status;
20582 mutex_unlock(&pHddCtx->tdls_lock);
20583
20584 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020585 {
20586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020587 FL("Link Establish Request Failed Status %ld"),
20588 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020589 return -EINVAL;
20590 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020591 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020592
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020593 mutex_lock(&pHddCtx->tdls_lock);
20594 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20595 if ( NULL == pTdlsPeer ) {
20596 mutex_unlock(&pHddCtx->tdls_lock);
20597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20598 "%s: " MAC_ADDRESS_STR
20599 " (oper %d) peer got freed in other context. ignored",
20600 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20601 return -EINVAL;
20602 }
20603
Atul Mittal115287b2014-07-08 13:26:33 +053020604 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20605 eTDLS_LINK_CONNECTED,
20606 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020607 staDesc.ucSTAId = pTdlsPeer->staId;
20608 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020609
20610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20611 "%s: tdlsLinkEstablishParams of peer "
20612 MAC_ADDRESS_STR "uapsdQueues: %d"
20613 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20614 "isResponder: %d peerstaId: %d",
20615 __func__,
20616 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20617 tdlsLinkEstablishParams.uapsdQueues,
20618 tdlsLinkEstablishParams.qos,
20619 tdlsLinkEstablishParams.maxSp,
20620 tdlsLinkEstablishParams.isBufSta,
20621 tdlsLinkEstablishParams.isOffChannelSupported,
20622 tdlsLinkEstablishParams.isResponder,
20623 pTdlsPeer->staId);
20624
20625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20626 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20627 __func__,
20628 staDesc.ucSTAId,
20629 staDesc.ucQosEnabled);
20630
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020631 ret = WLANTL_UpdateTdlsSTAClient(
20632 pHddCtx->pvosContext,
20633 &staDesc);
20634 if (ret != VOS_STATUS_SUCCESS) {
20635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20636 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020637
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020638 /* Mark TDLS client Authenticated .*/
20639 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20640 pTdlsPeer->staId,
20641 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020642 if (VOS_STATUS_SUCCESS == status)
20643 {
Hoonki Lee14621352013-04-16 17:51:19 -070020644 if (pTdlsPeer->is_responder == 0)
20645 {
20646 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020647 tdlsConnInfo_t *tdlsInfo;
20648
20649 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20650
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020651 if (!vos_timer_is_initialized(
20652 &pTdlsPeer->initiatorWaitTimeoutTimer))
20653 {
20654 /* Initialize initiator wait callback */
20655 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020656 &pTdlsPeer->initiatorWaitTimeoutTimer,
20657 VOS_TIMER_TYPE_SW,
20658 wlan_hdd_tdls_initiator_wait_cb,
20659 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020660 }
Hoonki Lee14621352013-04-16 17:51:19 -070020661 wlan_hdd_tdls_timer_restart(pAdapter,
20662 &pTdlsPeer->initiatorWaitTimeoutTimer,
20663 WAIT_TIME_TDLS_INITIATOR);
20664 /* suspend initiator TX until it receives direct packet from the
20665 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020666 ret = WLANTL_SuspendDataTx(
20667 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20668 &staId, NULL);
20669 if (ret != VOS_STATUS_SUCCESS) {
20670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20671 }
Hoonki Lee14621352013-04-16 17:51:19 -070020672 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020673
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020674 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020675 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020676 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020677 suppChannelLen =
20678 tdlsLinkEstablishParams.supportedChannelsLen;
20679
20680 if ((suppChannelLen > 0) &&
20681 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20682 {
20683 tANI_U8 suppPeerChannel = 0;
20684 int i = 0;
20685 for (i = 0U; i < suppChannelLen; i++)
20686 {
20687 suppPeerChannel =
20688 tdlsLinkEstablishParams.supportedChannels[i];
20689
20690 pTdlsPeer->isOffChannelSupported = FALSE;
20691 if (suppPeerChannel ==
20692 pTdlsPeer->peerParams.channel)
20693 {
20694 pTdlsPeer->isOffChannelSupported = TRUE;
20695 break;
20696 }
20697 }
20698 }
20699 else
20700 {
20701 pTdlsPeer->isOffChannelSupported = FALSE;
20702 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020703 }
20704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20705 "%s: TDLS channel switch request for channel "
20706 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020707 "%d isOffChannelSupported %d", __func__,
20708 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020709 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020710 suppChannelLen,
20711 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020712
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020713 /* TDLS Off Channel, Enable tdls channel switch,
20714 when their is only one tdls link and it supports */
20715 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20716 if ((numCurrTdlsPeers == 1) &&
20717 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20718 (TRUE == pTdlsPeer->isOffChannelConfigured))
20719 {
20720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20721 "%s: Send TDLS channel switch request for channel %d",
20722 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020723
20724 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020725 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20726 channel = pTdlsPeer->peerParams.channel;
20727
20728 mutex_unlock(&pHddCtx->tdls_lock);
20729
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020730 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20731 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020732 peerMac,
20733 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020734 TDLS_OFF_CHANNEL_BW_OFFSET,
20735 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020736 if (ret != VOS_STATUS_SUCCESS) {
20737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20738 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020739 }
20740 else
20741 {
20742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20743 "%s: TDLS channel switch request not sent"
20744 " numCurrTdlsPeers %d "
20745 "isOffChannelSupported %d "
20746 "isOffChannelConfigured %d",
20747 __func__, numCurrTdlsPeers,
20748 pTdlsPeer->isOffChannelSupported,
20749 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020750 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020751 }
20752
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020753 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020754 else
20755 mutex_unlock(&pHddCtx->tdls_lock);
20756
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020757 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020758
20759 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020760 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20761 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020762 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020763 int ac;
20764 uint8 ucAc[4] = { WLANTL_AC_VO,
20765 WLANTL_AC_VI,
20766 WLANTL_AC_BK,
20767 WLANTL_AC_BE };
20768 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20769 for(ac=0; ac < 4; ac++)
20770 {
20771 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20772 pTdlsPeer->staId, ucAc[ac],
20773 tlTid[ac], tlTid[ac], 0, 0,
20774 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020775 if (status != VOS_STATUS_SUCCESS) {
20776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20777 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020778 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020779 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020780 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020781
Bhargav Shah66896792015-10-01 18:17:37 +053020782 /* stop TCP delack timer if TDLS is enable */
20783 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20784 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020785 hdd_wlan_tdls_enable_link_event(peer,
20786 pTdlsPeer->isOffChannelSupported,
20787 pTdlsPeer->isOffChannelConfigured,
20788 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020789 }
20790 break;
20791 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020792 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020793 tANI_U16 numCurrTdlsPeers = 0;
20794 hddTdlsPeer_t *connPeer = NULL;
20795
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20797 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20798 __func__, MAC_ADDR_ARRAY(peer));
20799
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020800 mutex_lock(&pHddCtx->tdls_lock);
20801 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020802
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020803
Sunil Dutt41de4e22013-11-14 18:09:02 +053020804 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020805 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020806 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20807 " (oper %d) not exsting. ignored",
20808 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20809 return -EINVAL;
20810 }
20811
20812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20813 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20814 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20815 "NL80211_TDLS_DISABLE_LINK");
20816
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020817 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020818 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020819 long status;
20820
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020821 /* set tdls off channel status to false for this peer */
20822 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020823 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20824 eTDLS_LINK_TEARING,
20825 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20826 eTDLS_LINK_UNSPECIFIED:
20827 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020828 mutex_unlock(&pHddCtx->tdls_lock);
20829
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020830 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20831
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020832 status = sme_DeleteTdlsPeerSta(
20833 WLAN_HDD_GET_HAL_CTX(pAdapter),
20834 pAdapter->sessionId, peer );
20835 if (status != VOS_STATUS_SUCCESS) {
20836 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20837 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020838
20839 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20840 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020841
20842 mutex_lock(&pHddCtx->tdls_lock);
20843 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20844 if ( NULL == pTdlsPeer ) {
20845 mutex_unlock(&pHddCtx->tdls_lock);
20846 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20847 " peer was freed in other context",
20848 __func__, MAC_ADDR_ARRAY(peer));
20849 return -EINVAL;
20850 }
20851
Atul Mittal271a7652014-09-12 13:18:22 +053020852 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020853 eTDLS_LINK_IDLE,
20854 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020855 mutex_unlock(&pHddCtx->tdls_lock);
20856
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020857 if (status <= 0)
20858 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20860 "%s: Del station failed status %ld",
20861 __func__, status);
20862 return -EPERM;
20863 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020864
20865 /* TDLS Off Channel, Enable tdls channel switch,
20866 when their is only one tdls link and it supports */
20867 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20868 if (numCurrTdlsPeers == 1)
20869 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020870 tSirMacAddr peerMac;
20871 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020872
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020873 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020874 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020875
20876 if (connPeer == NULL) {
20877 mutex_unlock(&pHddCtx->tdls_lock);
20878 hddLog(VOS_TRACE_LEVEL_ERROR,
20879 "%s connPeer is NULL", __func__);
20880 return -EINVAL;
20881 }
20882
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020883 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20884 channel = connPeer->peerParams.channel;
20885
20886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20887 "%s: TDLS channel switch "
20888 "isOffChannelSupported %d "
20889 "isOffChannelConfigured %d "
20890 "isOffChannelEstablished %d",
20891 __func__,
20892 (connPeer ? connPeer->isOffChannelSupported : -1),
20893 (connPeer ? connPeer->isOffChannelConfigured : -1),
20894 (connPeer ? connPeer->isOffChannelEstablished : -1));
20895
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020896 if ((connPeer) &&
20897 (connPeer->isOffChannelSupported == TRUE) &&
20898 (connPeer->isOffChannelConfigured == TRUE))
20899 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020900 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020901 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020902 status = sme_SendTdlsChanSwitchReq(
20903 WLAN_HDD_GET_HAL_CTX(pAdapter),
20904 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020905 peerMac,
20906 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020907 TDLS_OFF_CHANNEL_BW_OFFSET,
20908 TDLS_CHANNEL_SWITCH_ENABLE);
20909 if (status != VOS_STATUS_SUCCESS) {
20910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20911 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020912 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020913 else
20914 mutex_unlock(&pHddCtx->tdls_lock);
20915 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020916 else
20917 {
20918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20919 "%s: TDLS channel switch request not sent "
20920 "numCurrTdlsPeers %d ",
20921 __func__, numCurrTdlsPeers);
20922 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020923 }
20924 else
20925 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020926 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20928 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020929 }
Bhargav Shah66896792015-10-01 18:17:37 +053020930 if (numCurrTdlsPeers == 0) {
20931 /* start TCP delack timer if TDLS is disable */
20932 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20933 hdd_manage_delack_timer(pHddCtx);
20934 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020935 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020936 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020937 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020938 {
Atul Mittal115287b2014-07-08 13:26:33 +053020939 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020940
Atul Mittal115287b2014-07-08 13:26:33 +053020941 if (0 != status)
20942 {
20943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020944 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020945 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020946 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020947 break;
20948 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020949 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020950 {
Atul Mittal115287b2014-07-08 13:26:33 +053020951 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20952 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020953 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020954 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020955
Atul Mittal115287b2014-07-08 13:26:33 +053020956 if (0 != status)
20957 {
20958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020959 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020960 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020961 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020962 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020963 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020964 case NL80211_TDLS_DISCOVERY_REQ:
20965 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020966 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020967 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020968 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020969 return -ENOTSUPP;
20970 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20972 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020973 return -ENOTSUPP;
20974 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020975
20976 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020977 return 0;
20978}
Chilam NG571c65a2013-01-19 12:27:36 +053020979
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020980static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20982 const u8 *peer,
20983#else
20984 u8 *peer,
20985#endif
20986 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020987{
20988 int ret;
20989
20990 vos_ssr_protect(__func__);
20991 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20992 vos_ssr_unprotect(__func__);
20993
20994 return ret;
20995}
20996
Chilam NG571c65a2013-01-19 12:27:36 +053020997int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20998 struct net_device *dev, u8 *peer)
20999{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021000 hddLog(VOS_TRACE_LEVEL_INFO,
21001 "tdls send discover req: "MAC_ADDRESS_STR,
21002 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021003#if TDLS_MGMT_VERSION2
21004 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21005 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21006#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21008 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21009 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21010#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21011 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21012 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21013#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21014 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21015 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21016#else
Chilam NG571c65a2013-01-19 12:27:36 +053021017 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21018 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021019#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021020#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021021}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021022#endif
21023
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021024#ifdef WLAN_FEATURE_GTK_OFFLOAD
21025/*
21026 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21027 * Callback rountine called upon receiving response for
21028 * get offload info
21029 */
21030void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21031 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21032{
21033
21034 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021035 tANI_U8 tempReplayCounter[8];
21036 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021037
21038 ENTER();
21039
21040 if (NULL == pAdapter)
21041 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021043 "%s: HDD adapter is Null", __func__);
21044 return ;
21045 }
21046
21047 if (NULL == pGtkOffloadGetInfoRsp)
21048 {
21049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21050 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21051 return ;
21052 }
21053
21054 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21055 {
21056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21057 "%s: wlan Failed to get replay counter value",
21058 __func__);
21059 return ;
21060 }
21061
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021062 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21063 /* Update replay counter */
21064 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21065 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21066
21067 {
21068 /* changing from little to big endian since supplicant
21069 * works on big endian format
21070 */
21071 int i;
21072 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21073
21074 for (i = 0; i < 8; i++)
21075 {
21076 tempReplayCounter[7-i] = (tANI_U8)p[i];
21077 }
21078 }
21079
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021080 /* Update replay counter to NL */
21081 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021082 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021083}
21084
21085/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021086 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021087 * This function is used to offload GTK rekeying job to the firmware.
21088 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021089int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021090 struct cfg80211_gtk_rekey_data *data)
21091{
21092 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21093 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21094 hdd_station_ctx_t *pHddStaCtx;
21095 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021096 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021097 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021098 eHalStatus status = eHAL_STATUS_FAILURE;
21099
21100 ENTER();
21101
21102 if (NULL == pAdapter)
21103 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021105 "%s: HDD adapter is Null", __func__);
21106 return -ENODEV;
21107 }
21108
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021109 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21110 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21111 pAdapter->sessionId, pAdapter->device_mode));
21112
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021113 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021114 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021116 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021117 }
21118
21119 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21120 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21121 if (NULL == hHal)
21122 {
21123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21124 "%s: HAL context is Null!!!", __func__);
21125 return -EAGAIN;
21126 }
21127
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021128 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21129 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21130 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21131 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021132 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021133 {
21134 /* changing from big to little endian since driver
21135 * works on little endian format
21136 */
21137 tANI_U8 *p =
21138 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21139 int i;
21140
21141 for (i = 0; i < 8; i++)
21142 {
21143 p[7-i] = data->replay_ctr[i];
21144 }
21145 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021146
21147 if (TRUE == pHddCtx->hdd_wlan_suspended)
21148 {
21149 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021150 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21151 sizeof (tSirGtkOffloadParams));
21152 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021153 pAdapter->sessionId);
21154
21155 if (eHAL_STATUS_SUCCESS != status)
21156 {
21157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21158 "%s: sme_SetGTKOffload failed, returned %d",
21159 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021160
21161 /* Need to clear any trace of key value in the memory.
21162 * Thus zero out the memory even though it is local
21163 * variable.
21164 */
21165 vos_mem_zero(&hddGtkOffloadReqParams,
21166 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021167 return status;
21168 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21170 "%s: sme_SetGTKOffload successfull", __func__);
21171 }
21172 else
21173 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21175 "%s: wlan not suspended GTKOffload request is stored",
21176 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021177 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021178
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021179 /* Need to clear any trace of key value in the memory.
21180 * Thus zero out the memory even though it is local
21181 * variable.
21182 */
21183 vos_mem_zero(&hddGtkOffloadReqParams,
21184 sizeof(hddGtkOffloadReqParams));
21185
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021186 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021187 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021188}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021189
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021190int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21191 struct cfg80211_gtk_rekey_data *data)
21192{
21193 int ret;
21194
21195 vos_ssr_protect(__func__);
21196 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21197 vos_ssr_unprotect(__func__);
21198
21199 return ret;
21200}
21201#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021202/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021203 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021204 * This function is used to set access control policy
21205 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021206static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21207 struct net_device *dev,
21208 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021209{
21210 int i;
21211 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21212 hdd_hostapd_state_t *pHostapdState;
21213 tsap_Config_t *pConfig;
21214 v_CONTEXT_t pVosContext = NULL;
21215 hdd_context_t *pHddCtx;
21216 int status;
21217
21218 ENTER();
21219
21220 if (NULL == pAdapter)
21221 {
21222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21223 "%s: HDD adapter is Null", __func__);
21224 return -ENODEV;
21225 }
21226
21227 if (NULL == params)
21228 {
21229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21230 "%s: params is Null", __func__);
21231 return -EINVAL;
21232 }
21233
21234 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21235 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021236 if (0 != status)
21237 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021238 return status;
21239 }
21240
21241 pVosContext = pHddCtx->pvosContext;
21242 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21243
21244 if (NULL == pHostapdState)
21245 {
21246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21247 "%s: pHostapdState is Null", __func__);
21248 return -EINVAL;
21249 }
21250
21251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21252 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021253 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21254 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21255 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021256
21257 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21258 {
21259 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21260
21261 /* default value */
21262 pConfig->num_accept_mac = 0;
21263 pConfig->num_deny_mac = 0;
21264
21265 /**
21266 * access control policy
21267 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21268 * listed in hostapd.deny file.
21269 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21270 * listed in hostapd.accept file.
21271 */
21272 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21273 {
21274 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21275 }
21276 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21277 {
21278 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21279 }
21280 else
21281 {
21282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21283 "%s:Acl Policy : %d is not supported",
21284 __func__, params->acl_policy);
21285 return -ENOTSUPP;
21286 }
21287
21288 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21289 {
21290 pConfig->num_accept_mac = params->n_acl_entries;
21291 for (i = 0; i < params->n_acl_entries; i++)
21292 {
21293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21294 "** Add ACL MAC entry %i in WhiletList :"
21295 MAC_ADDRESS_STR, i,
21296 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21297
21298 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21299 sizeof(qcmacaddr));
21300 }
21301 }
21302 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21303 {
21304 pConfig->num_deny_mac = params->n_acl_entries;
21305 for (i = 0; i < params->n_acl_entries; i++)
21306 {
21307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21308 "** Add ACL MAC entry %i in BlackList :"
21309 MAC_ADDRESS_STR, i,
21310 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21311
21312 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21313 sizeof(qcmacaddr));
21314 }
21315 }
21316
21317 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21318 {
21319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21320 "%s: SAP Set Mac Acl fail", __func__);
21321 return -EINVAL;
21322 }
21323 }
21324 else
21325 {
21326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021327 "%s: Invalid device_mode = %s (%d)",
21328 __func__, hdd_device_modetoString(pAdapter->device_mode),
21329 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021330 return -EINVAL;
21331 }
21332
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021333 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021334 return 0;
21335}
21336
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021337static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21338 struct net_device *dev,
21339 const struct cfg80211_acl_data *params)
21340{
21341 int ret;
21342 vos_ssr_protect(__func__);
21343 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21344 vos_ssr_unprotect(__func__);
21345
21346 return ret;
21347}
21348
Leo Chang9056f462013-08-01 19:21:11 -070021349#ifdef WLAN_NL80211_TESTMODE
21350#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021351void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021352(
21353 void *pAdapter,
21354 void *indCont
21355)
21356{
Leo Changd9df8aa2013-09-26 13:32:26 -070021357 tSirLPHBInd *lphbInd;
21358 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021359 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021360
21361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021362 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021363
c_hpothu73f35e62014-04-18 13:40:08 +053021364 if (pAdapter == NULL)
21365 {
21366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21367 "%s: pAdapter is NULL\n",__func__);
21368 return;
21369 }
21370
Leo Chang9056f462013-08-01 19:21:11 -070021371 if (NULL == indCont)
21372 {
21373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021374 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021375 return;
21376 }
21377
c_hpothu73f35e62014-04-18 13:40:08 +053021378 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021379 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021380 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021381 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021382 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021383 GFP_ATOMIC);
21384 if (!skb)
21385 {
21386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21387 "LPHB timeout, NL buffer alloc fail");
21388 return;
21389 }
21390
Leo Changac3ba772013-10-07 09:47:04 -070021391 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021392 {
21393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21394 "WLAN_HDD_TM_ATTR_CMD put fail");
21395 goto nla_put_failure;
21396 }
Leo Changac3ba772013-10-07 09:47:04 -070021397 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021398 {
21399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21400 "WLAN_HDD_TM_ATTR_TYPE put fail");
21401 goto nla_put_failure;
21402 }
Leo Changac3ba772013-10-07 09:47:04 -070021403 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021404 sizeof(tSirLPHBInd), lphbInd))
21405 {
21406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21407 "WLAN_HDD_TM_ATTR_DATA put fail");
21408 goto nla_put_failure;
21409 }
Leo Chang9056f462013-08-01 19:21:11 -070021410 cfg80211_testmode_event(skb, GFP_ATOMIC);
21411 return;
21412
21413nla_put_failure:
21414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21415 "NLA Put fail");
21416 kfree_skb(skb);
21417
21418 return;
21419}
21420#endif /* FEATURE_WLAN_LPHB */
21421
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021422static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021423{
21424 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21425 int err = 0;
21426#ifdef FEATURE_WLAN_LPHB
21427 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021428 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021429
21430 ENTER();
21431
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021432 err = wlan_hdd_validate_context(pHddCtx);
21433 if (0 != err)
21434 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021435 return err;
21436 }
Leo Chang9056f462013-08-01 19:21:11 -070021437#endif /* FEATURE_WLAN_LPHB */
21438
21439 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21440 if (err)
21441 {
21442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21443 "%s Testmode INV ATTR", __func__);
21444 return err;
21445 }
21446
21447 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21448 {
21449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21450 "%s Testmode INV CMD", __func__);
21451 return -EINVAL;
21452 }
21453
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021454 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21455 TRACE_CODE_HDD_CFG80211_TESTMODE,
21456 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021457 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21458 {
21459#ifdef FEATURE_WLAN_LPHB
21460 /* Low Power Heartbeat configuration request */
21461 case WLAN_HDD_TM_CMD_WLAN_HB:
21462 {
21463 int buf_len;
21464 void *buf;
21465 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021466 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021467
21468 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21469 {
21470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21471 "%s Testmode INV DATA", __func__);
21472 return -EINVAL;
21473 }
21474
21475 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21476 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021477
Manjeet Singh3c577442017-02-10 19:03:38 +053021478 if (buf_len > sizeof(*hb_params)) {
21479 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21480 buf_len);
21481 return -ERANGE;
21482 }
21483
Amar Singhal05852702014-02-04 14:40:00 -080021484 hb_params_temp =(tSirLPHBReq *)buf;
21485 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21486 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21487 return -EINVAL;
21488
Leo Chang9056f462013-08-01 19:21:11 -070021489 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21490 if (NULL == hb_params)
21491 {
21492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21493 "%s Request Buffer Alloc Fail", __func__);
21494 return -EINVAL;
21495 }
21496
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021497 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021498 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021499 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21500 hb_params,
21501 wlan_hdd_cfg80211_lphb_ind_handler);
21502 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021503 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21505 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021506 vos_mem_free(hb_params);
21507 }
Leo Chang9056f462013-08-01 19:21:11 -070021508 return 0;
21509 }
21510#endif /* FEATURE_WLAN_LPHB */
21511 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21513 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021514 return -EOPNOTSUPP;
21515 }
21516
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021517 EXIT();
21518 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021519}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021520
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021521static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21523 struct wireless_dev *wdev,
21524#endif
21525 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021526{
21527 int ret;
21528
21529 vos_ssr_protect(__func__);
21530 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21531 vos_ssr_unprotect(__func__);
21532
21533 return ret;
21534}
Leo Chang9056f462013-08-01 19:21:11 -070021535#endif /* CONFIG_NL80211_TESTMODE */
21536
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021537extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021538static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021539 struct net_device *dev,
21540 int idx, struct survey_info *survey)
21541{
21542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21543 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021544 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021545 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021546 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021547 v_S7_t snr,rssi;
21548 int status, i, j, filled = 0;
21549
21550 ENTER();
21551
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021552 if (NULL == pAdapter)
21553 {
21554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21555 "%s: HDD adapter is Null", __func__);
21556 return -ENODEV;
21557 }
21558
21559 if (NULL == wiphy)
21560 {
21561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21562 "%s: wiphy is Null", __func__);
21563 return -ENODEV;
21564 }
21565
21566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21567 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021568 if (0 != status)
21569 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021570 return status;
21571 }
21572
Mihir Sheted9072e02013-08-21 17:02:29 +053021573 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21574
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021575 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021576 0 != pAdapter->survey_idx ||
21577 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021578 {
21579 /* The survey dump ops when implemented completely is expected to
21580 * return a survey of all channels and the ops is called by the
21581 * kernel with incremental values of the argument 'idx' till it
21582 * returns -ENONET. But we can only support the survey for the
21583 * operating channel for now. survey_idx is used to track
21584 * that the ops is called only once and then return -ENONET for
21585 * the next iteration
21586 */
21587 pAdapter->survey_idx = 0;
21588 return -ENONET;
21589 }
21590
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021591 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21592 {
21593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21594 "%s: Roaming in progress, hence return ", __func__);
21595 return -ENONET;
21596 }
21597
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021598 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21599
21600 wlan_hdd_get_snr(pAdapter, &snr);
21601 wlan_hdd_get_rssi(pAdapter, &rssi);
21602
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021603 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21604 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21605 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021606 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21607 hdd_wlan_get_freq(channel, &freq);
21608
21609
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021610 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021611 {
21612 if (NULL == wiphy->bands[i])
21613 {
21614 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21615 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21616 continue;
21617 }
21618
21619 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21620 {
21621 struct ieee80211_supported_band *band = wiphy->bands[i];
21622
21623 if (band->channels[j].center_freq == (v_U16_t)freq)
21624 {
21625 survey->channel = &band->channels[j];
21626 /* The Rx BDs contain SNR values in dB for the received frames
21627 * while the supplicant expects noise. So we calculate and
21628 * return the value of noise (dBm)
21629 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21630 */
21631 survey->noise = rssi - snr;
21632 survey->filled = SURVEY_INFO_NOISE_DBM;
21633 filled = 1;
21634 }
21635 }
21636 }
21637
21638 if (filled)
21639 pAdapter->survey_idx = 1;
21640 else
21641 {
21642 pAdapter->survey_idx = 0;
21643 return -ENONET;
21644 }
21645
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021646 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021647 return 0;
21648}
21649
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021650static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21651 struct net_device *dev,
21652 int idx, struct survey_info *survey)
21653{
21654 int ret;
21655
21656 vos_ssr_protect(__func__);
21657 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21658 vos_ssr_unprotect(__func__);
21659
21660 return ret;
21661}
21662
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021663/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021664 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021665 * this is called when cfg80211 driver resume
21666 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21667 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021668int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021669{
21670 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21671 hdd_adapter_t *pAdapter;
21672 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21673 VOS_STATUS status = VOS_STATUS_SUCCESS;
21674
21675 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021676
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021677 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021678 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021679 return 0;
21680 }
21681
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021682 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21683 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021684
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021685 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021686 {
21687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21688 "%s: Resume SoftAP", __func__);
21689 hdd_set_wlan_suspend_mode(false);
21690 }
21691
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021692 spin_lock(&pHddCtx->schedScan_lock);
21693 pHddCtx->isWiphySuspended = FALSE;
21694 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21695 {
21696 spin_unlock(&pHddCtx->schedScan_lock);
21697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21698 "%s: Return resume is not due to PNO indication", __func__);
21699 return 0;
21700 }
21701 // Reset flag to avoid updatating cfg80211 data old results again
21702 pHddCtx->isSchedScanUpdatePending = FALSE;
21703 spin_unlock(&pHddCtx->schedScan_lock);
21704
21705 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21706
21707 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21708 {
21709 pAdapter = pAdapterNode->pAdapter;
21710 if ( (NULL != pAdapter) &&
21711 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21712 {
21713 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021714 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21716 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021717 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021718 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021719 {
21720 /* Acquire wakelock to handle the case where APP's tries to
21721 * suspend immediately after updating the scan results. Whis
21722 * results in app's is in suspended state and not able to
21723 * process the connect request to AP
21724 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021725 hdd_prevent_suspend_timeout(2000,
21726 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021727 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021728 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021729
21730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21731 "%s : cfg80211 scan result database updated", __func__);
21732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021733 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021734 return 0;
21735
21736 }
21737 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21738 pAdapterNode = pNext;
21739 }
21740
21741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21742 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021743 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021744 return 0;
21745}
21746
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021747int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21748{
21749 int ret;
21750
21751 vos_ssr_protect(__func__);
21752 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21753 vos_ssr_unprotect(__func__);
21754
21755 return ret;
21756}
21757
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021758/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021759 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021760 * this is called when cfg80211 driver suspends
21761 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021762int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021763 struct cfg80211_wowlan *wow)
21764{
21765 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021766 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021767
21768 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021769
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021770 ret = wlan_hdd_validate_context(pHddCtx);
21771 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021772 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021773 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021774 }
21775
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021776 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21778 "%s: Suspend SoftAP", __func__);
21779 hdd_set_wlan_suspend_mode(true);
21780 }
21781
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021782
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021783 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21784 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21785 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021786 pHddCtx->isWiphySuspended = TRUE;
21787
21788 EXIT();
21789
21790 return 0;
21791}
21792
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021793int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21794 struct cfg80211_wowlan *wow)
21795{
21796 int ret;
21797
21798 vos_ssr_protect(__func__);
21799 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21800 vos_ssr_unprotect(__func__);
21801
21802 return ret;
21803}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021804
21805#ifdef FEATURE_OEM_DATA_SUPPORT
21806static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021807 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021808{
21809 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21810
21811 ENTER();
21812
21813 if (wlan_hdd_validate_context(pHddCtx)) {
21814 return;
21815 }
21816 if (!pMsg)
21817 {
21818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21819 return;
21820 }
21821
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021822 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021823
21824 EXIT();
21825 return;
21826
21827}
21828
21829void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021830 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021831{
21832 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21833
21834 ENTER();
21835
21836 if (wlan_hdd_validate_context(pHddCtx)) {
21837 return;
21838 }
21839
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021840 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021841
21842 switch(evType) {
21843 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021844 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021845 break;
21846 default:
21847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21848 break;
21849 }
21850 EXIT();
21851}
21852#endif
21853
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021854#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21855 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021856/**
21857 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21858 * @wiphy: Pointer to wiphy
21859 * @wdev: Pointer to wireless device structure
21860 *
21861 * This function is used to abort an ongoing scan
21862 *
21863 * Return: None
21864 */
21865static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21866 struct wireless_dev *wdev)
21867{
21868 struct net_device *dev = wdev->netdev;
21869 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21870 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21871 int ret;
21872
21873 ENTER();
21874
21875 if (NULL == adapter) {
21876 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21877 return;
21878 }
21879
21880 ret = wlan_hdd_validate_context(hdd_ctx);
21881 if (0 != ret)
21882 return;
21883
21884 wlan_hdd_scan_abort(adapter);
21885
21886 return;
21887}
21888
21889/**
21890 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21891 * @wiphy: Pointer to wiphy
21892 * @wdev: Pointer to wireless device structure
21893 *
21894 * Return: None
21895 */
21896void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21897 struct wireless_dev *wdev)
21898{
21899 vos_ssr_protect(__func__);
21900 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21901 vos_ssr_unprotect(__func__);
21902
21903 return;
21904}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021905#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021906
Abhishek Singh936c6932017-11-07 17:28:23 +053021907#ifdef CHANNEL_SWITCH_SUPPORTED
21908/**
21909 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21910 * channel in SAP/GO
21911 * @wiphy: wiphy pointer
21912 * @dev: dev pointer.
21913 * @csa_params: Change channel params
21914 *
21915 * This function is called to switch channel in SAP/GO
21916 *
21917 * Return: 0 if success else return non zero
21918 */
21919static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21920 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21921{
21922 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21923 hdd_context_t *hdd_ctx;
21924 uint8_t channel;
21925 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021926 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053021927 v_CONTEXT_t vos_ctx;
21928
21929 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21930
21931 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21932 ret = wlan_hdd_validate_context(hdd_ctx);
21933 if (ret)
21934 return ret;
21935
21936 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21937 if (!vos_ctx) {
21938 hddLog(LOGE, FL("Vos ctx is null"));
21939 return -EINVAL;
21940 }
21941
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021942 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053021943 return -ENOTSUPP;
21944
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021945 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
21946 if (!sap_ctx) {
21947 hddLog(LOGE, FL("sap_ctx is NULL"));
21948 return -EINVAL;
21949 }
21950
21951 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
21952 if (ret)
21953 return ret;
21954
21955 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
21956
Abhishek Singh936c6932017-11-07 17:28:23 +053021957 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021958 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021959
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021960 if (ret) {
21961 wlansap_reset_chan_change_in_progress(sap_ctx);
21962 complete(&sap_ctx->ecsa_info.chan_switch_comp);
21963 }
21964
Abhishek Singh936c6932017-11-07 17:28:23 +053021965 return ret;
21966}
21967
21968/**
21969 * wlan_hdd_cfg80211_channel_switch()- function to switch
21970 * channel in SAP/GO
21971 * @wiphy: wiphy pointer
21972 * @dev: dev pointer.
21973 * @csa_params: Change channel params
21974 *
21975 * This function is called to switch channel in SAP/GO
21976 *
21977 * Return: 0 if success else return non zero
21978 */
21979static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21980 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21981{
21982 int ret;
21983
21984 vos_ssr_protect(__func__);
21985 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21986 vos_ssr_unprotect(__func__);
21987
21988 return ret;
21989}
21990#endif
21991
Jeff Johnson295189b2012-06-20 16:38:30 -070021992/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021993static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021994{
21995 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21996 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21997 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21998 .change_station = wlan_hdd_change_station,
21999#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22000 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22001 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22002 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022003#else
22004 .start_ap = wlan_hdd_cfg80211_start_ap,
22005 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22006 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022007#endif
22008 .change_bss = wlan_hdd_cfg80211_change_bss,
22009 .add_key = wlan_hdd_cfg80211_add_key,
22010 .get_key = wlan_hdd_cfg80211_get_key,
22011 .del_key = wlan_hdd_cfg80211_del_key,
22012 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022013#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022014 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022015#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022016 .scan = wlan_hdd_cfg80211_scan,
22017 .connect = wlan_hdd_cfg80211_connect,
22018 .disconnect = wlan_hdd_cfg80211_disconnect,
22019 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22020 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22021 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22022 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22023 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022024 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22025 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022026 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22028 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22029 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22030 .set_txq_params = wlan_hdd_set_txq_params,
22031#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022032 .get_station = wlan_hdd_cfg80211_get_station,
22033 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22034 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022035 .add_station = wlan_hdd_cfg80211_add_station,
22036#ifdef FEATURE_WLAN_LFR
22037 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22038 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22039 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22040#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022041#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22042 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22043#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022044#ifdef FEATURE_WLAN_TDLS
22045 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22046 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22047#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022048#ifdef WLAN_FEATURE_GTK_OFFLOAD
22049 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22050#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022051#ifdef FEATURE_WLAN_SCAN_PNO
22052 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22053 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22054#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022055 .resume = wlan_hdd_cfg80211_resume_wlan,
22056 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022057 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022058#ifdef WLAN_NL80211_TESTMODE
22059 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22060#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022061 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22063 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022064 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022065#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022066#ifdef CHANNEL_SWITCH_SUPPORTED
22067 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22068#endif
22069
Jeff Johnson295189b2012-06-20 16:38:30 -070022070};
22071