blob: ea392395949d2597e6578969b2f5f454ae648bd6 [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
Jeff Johnson295189b2012-06-20 16:38:30 -0700462static struct cfg80211_ops wlan_hdd_cfg80211_ops;
463
464/* Data rate 100KBPS based on IE Index */
465struct index_data_rate_type
466{
467 v_U8_t beacon_rate_index;
468 v_U16_t supported_rate[4];
469};
470
471/* 11B, 11G Rate table include Basic rate and Extended rate
472 The IDX field is the rate index
473 The HI field is the rate when RSSI is strong or being ignored
474 (in this case we report actual rate)
475 The MID field is the rate when RSSI is moderate
476 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
477 The LO field is the rate when RSSI is low
478 (in this case we don't report rates, actual current rate used)
479 */
480static const struct
481{
482 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700484} supported_data_rate[] =
485{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700486/* IDX HI HM LM LO (RSSI-based index */
487 {2, { 10, 10, 10, 0}},
488 {4, { 20, 20, 10, 0}},
489 {11, { 55, 20, 10, 0}},
490 {12, { 60, 55, 20, 0}},
491 {18, { 90, 55, 20, 0}},
492 {22, {110, 55, 20, 0}},
493 {24, {120, 90, 60, 0}},
494 {36, {180, 120, 60, 0}},
495 {44, {220, 180, 60, 0}},
496 {48, {240, 180, 90, 0}},
497 {66, {330, 180, 90, 0}},
498 {72, {360, 240, 90, 0}},
499 {96, {480, 240, 120, 0}},
500 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700501};
502
503/* MCS Based rate table */
504static struct index_data_rate_type supported_mcs_rate[] =
505{
506/* MCS L20 L40 S20 S40 */
507 {0, {65, 135, 72, 150}},
508 {1, {130, 270, 144, 300}},
509 {2, {195, 405, 217, 450}},
510 {3, {260, 540, 289, 600}},
511 {4, {390, 810, 433, 900}},
512 {5, {520, 1080, 578, 1200}},
513 {6, {585, 1215, 650, 1350}},
514 {7, {650, 1350, 722, 1500}}
515};
516
Leo Chang6f8870f2013-03-26 18:11:36 -0700517#ifdef WLAN_FEATURE_11AC
518
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530519#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700520
521struct index_vht_data_rate_type
522{
523 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524 v_U16_t supported_VHT80_rate[2];
525 v_U16_t supported_VHT40_rate[2];
526 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700527};
528
529typedef enum
530{
531 DATA_RATE_11AC_MAX_MCS_7,
532 DATA_RATE_11AC_MAX_MCS_8,
533 DATA_RATE_11AC_MAX_MCS_9,
534 DATA_RATE_11AC_MAX_MCS_NA
535} eDataRate11ACMaxMcs;
536
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530537/* SSID broadcast type */
538typedef enum eSSIDBcastType
539{
540 eBCAST_UNKNOWN = 0,
541 eBCAST_NORMAL = 1,
542 eBCAST_HIDDEN = 2,
543} tSSIDBcastType;
544
Leo Chang6f8870f2013-03-26 18:11:36 -0700545/* MCS Based VHT rate table */
546static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
547{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530548/* MCS L80 S80 L40 S40 L20 S40*/
549 {0, {293, 325}, {135, 150}, {65, 72}},
550 {1, {585, 650}, {270, 300}, {130, 144}},
551 {2, {878, 975}, {405, 450}, {195, 217}},
552 {3, {1170, 1300}, {540, 600}, {260, 289}},
553 {4, {1755, 1950}, {810, 900}, {390, 433}},
554 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
555 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
556 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
557 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
558 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700559};
560#endif /* WLAN_FEATURE_11AC */
561
c_hpothu79aab322014-07-14 21:11:01 +0530562/*array index points to MCS and array value points respective rssi*/
563static int rssiMcsTbl[][10] =
564{
565/*MCS 0 1 2 3 4 5 6 7 8 9*/
566 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
567 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
568 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
569};
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530572#ifdef FEATURE_WLAN_SCAN_PNO
573static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
Leo Chang9056f462013-08-01 19:21:11 -0700576#ifdef WLAN_NL80211_TESTMODE
577enum wlan_hdd_tm_attr
578{
579 WLAN_HDD_TM_ATTR_INVALID = 0,
580 WLAN_HDD_TM_ATTR_CMD = 1,
581 WLAN_HDD_TM_ATTR_DATA = 2,
582 WLAN_HDD_TM_ATTR_TYPE = 3,
583 /* keep last */
584 WLAN_HDD_TM_ATTR_AFTER_LAST,
585 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
586};
587
588enum wlan_hdd_tm_cmd
589{
590 WLAN_HDD_TM_CMD_WLAN_HB = 1,
591};
592
593#define WLAN_HDD_TM_DATA_MAX_LEN 5000
594
595static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
596{
597 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
598 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
599 .len = WLAN_HDD_TM_DATA_MAX_LEN },
600};
601#endif /* WLAN_NL80211_TESTMODE */
602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800603#ifdef FEATURE_WLAN_CH_AVOID
604/*
605 * FUNCTION: wlan_hdd_send_avoid_freq_event
606 * This is called when wlan driver needs to send vendor specific
607 * avoid frequency range event to userspace
608 */
609int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
610 tHddAvoidFreqList *pAvoidFreqList)
611{
612 struct sk_buff *vendor_event;
613
614 ENTER();
615
616 if (!pHddCtx)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: HDD context is null", __func__);
620 return -1;
621 }
622
623 if (!pAvoidFreqList)
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
626 "%s: pAvoidFreqList is null", __func__);
627 return -1;
628 }
629
630 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
632 NULL,
633#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800634 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 GFP_KERNEL);
637 if (!vendor_event)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
640 "%s: cfg80211_vendor_event_alloc failed", __func__);
641 return -1;
642 }
643
644 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
645 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
646
647 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
648
649 EXIT();
650 return 0;
651}
652#endif /* FEATURE_WLAN_CH_AVOID */
653
Srinivas Dasari030bad32015-02-18 23:23:54 +0530654/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530655 * define short names for the global vendor params
656 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
657 */
658#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
659
660/**
661 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
662 * hang reason
663 * @reason: cds recovery reason
664 *
665 * Return: Vendor specific reason code
666 */
667static enum qca_wlan_vendor_hang_reason
668hdd_convert_hang_reason(enum vos_hang_reason reason)
669{
670 unsigned int ret_val;
671
672 switch (reason) {
673 case VOS_GET_MSG_BUFF_FAILURE:
674 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
675 break;
676 case VOS_ACTIVE_LIST_TIMEOUT:
677 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
678 break;
679 case VOS_SCAN_REQ_EXPIRED:
680 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
681 break;
682 case VOS_TRANSMISSIONS_TIMEOUT:
683 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
684 break;
685 case VOS_DXE_FAILURE:
686 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
687 break;
688 case VOS_WDI_FAILURE:
689 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
690 break;
691 case VOS_REASON_UNSPECIFIED:
692 default:
693 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
694 }
695 return ret_val;
696}
697
698/**
699 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
700 * @hdd_ctx: Pointer to hdd context
701 * @reason: cds recovery reason
702 *
703 * Return: 0 on success or failure reason
704 */
705int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
706 enum vos_hang_reason reason)
707{
708 struct sk_buff *vendor_event;
709 enum qca_wlan_vendor_hang_reason hang_reason;
710
711 ENTER();
712
713 if (!hdd_ctx) {
714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
715 "HDD context is null");
716 return -EINVAL;
717 }
718
719 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
721 NULL,
722#endif
723 sizeof(unsigned int),
724 HANG_REASON_INDEX,
725 GFP_KERNEL);
726 if (!vendor_event) {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "cfg80211_vendor_event_alloc failed");
729 return -ENOMEM;
730 }
731
732 hang_reason = hdd_convert_hang_reason(reason);
733
734 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
735 (unsigned int) hang_reason)) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
738 kfree_skb(vendor_event);
739 return -EINVAL;
740 }
741
742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
743
744 EXIT();
745 return 0;
746}
747#undef HANG_REASON_INDEX
748
749/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530750 * FUNCTION: __wlan_hdd_cfg80211_nan_request
751 * This is called when wlan driver needs to send vendor specific
752 * nan request event.
753 */
754static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
755 struct wireless_dev *wdev,
756 const void *data, int data_len)
757{
758 tNanRequestReq nan_req;
759 VOS_STATUS status;
760 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530761 struct net_device *dev = wdev->netdev;
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
765
766 if (0 == data_len)
767 {
768 hddLog(VOS_TRACE_LEVEL_ERROR,
769 FL("NAN - Invalid Request, length = 0"));
770 return ret_val;
771 }
772
773 if (NULL == data)
774 {
775 hddLog(VOS_TRACE_LEVEL_ERROR,
776 FL("NAN - Invalid Request, data is NULL"));
777 return ret_val;
778 }
779
780 status = wlan_hdd_validate_context(pHddCtx);
781 if (0 != status)
782 {
783 hddLog(VOS_TRACE_LEVEL_ERROR,
784 FL("HDD context is not valid"));
785 return -EINVAL;
786 }
787
788 hddLog(LOG1, FL("Received NAN command"));
789 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
790 (tANI_U8 *)data, data_len);
791
792 /* check the NAN Capability */
793 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
794 {
795 hddLog(VOS_TRACE_LEVEL_ERROR,
796 FL("NAN is not supported by Firmware"));
797 return -EINVAL;
798 }
799
800 nan_req.request_data_len = data_len;
801 nan_req.request_data = data;
802
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530803 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530804 if (VOS_STATUS_SUCCESS == status)
805 {
806 ret_val = 0;
807 }
808 return ret_val;
809}
810
811/*
812 * FUNCTION: wlan_hdd_cfg80211_nan_request
813 * Wrapper to protect the nan vendor command from ssr
814 */
815static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
816 struct wireless_dev *wdev,
817 const void *data, int data_len)
818{
819 int ret;
820
821 vos_ssr_protect(__func__);
822 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
823 vos_ssr_unprotect(__func__);
824
825 return ret;
826}
827
828/*
829 * FUNCTION: wlan_hdd_cfg80211_nan_callback
830 * This is a callback function and it gets called
831 * when we need to report nan response event to
832 * upper layers.
833 */
834static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
835{
836 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
837 struct sk_buff *vendor_event;
838 int status;
839 tSirNanEvent *data;
840
841 ENTER();
842 if (NULL == msg)
843 {
844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
845 FL(" msg received here is null"));
846 return;
847 }
848 data = msg;
849
850 status = wlan_hdd_validate_context(pHddCtx);
851
852 if (0 != status)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL("HDD context is not valid"));
856 return;
857 }
858
859 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
861 NULL,
862#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530863 data->event_data_len +
864 NLMSG_HDRLEN,
865 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
866 GFP_KERNEL);
867
868 if (!vendor_event)
869 {
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
871 FL("cfg80211_vendor_event_alloc failed"));
872 return;
873 }
874 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
875 data->event_data_len, data->event_data))
876 {
877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
878 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
879 kfree_skb(vendor_event);
880 return;
881 }
882 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
883 EXIT();
884}
885
886/*
887 * FUNCTION: wlan_hdd_cfg80211_nan_init
888 * This function is called to register the callback to sme layer
889 */
890inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
891{
892 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
893}
894
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530895/*
896 * define short names for the global vendor params
897 * used by __wlan_hdd_cfg80211_get_station_cmd()
898 */
899#define STATION_INVALID \
900 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
901#define STATION_INFO \
902 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
903#define STATION_ASSOC_FAIL_REASON \
904 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530905#define STATION_REMOTE \
906 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530907#define STATION_MAX \
908 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
909
910static const struct nla_policy
911hdd_get_station_policy[STATION_MAX + 1] = {
912 [STATION_INFO] = {.type = NLA_FLAG},
913 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
914};
915
916/**
917 * hdd_get_station_assoc_fail() - Handle get station assoc fail
918 * @hdd_ctx: HDD context within host driver
919 * @wdev: wireless device
920 *
921 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
922 * Validate cmd attributes and send the station info to upper layers.
923 *
924 * Return: Success(0) or reason code for failure
925 */
926static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
927 hdd_adapter_t *adapter)
928{
929 struct sk_buff *skb = NULL;
930 uint32_t nl_buf_len;
931 hdd_station_ctx_t *hdd_sta_ctx;
932
933 nl_buf_len = NLMSG_HDRLEN;
934 nl_buf_len += sizeof(uint32_t);
935 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
936
937 if (!skb) {
938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
939 return -ENOMEM;
940 }
941
942 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
943
944 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
945 hdd_sta_ctx->conn_info.assoc_status_code)) {
946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
947 goto fail;
948 }
949 return cfg80211_vendor_cmd_reply(skb);
950fail:
951 if (skb)
952 kfree_skb(skb);
953 return -EINVAL;
954}
955
956/**
957 * hdd_map_auth_type() - transform auth type specific to
958 * vendor command
959 * @auth_type: csr auth type
960 *
961 * Return: Success(0) or reason code for failure
962 */
963static int hdd_convert_auth_type(uint32_t auth_type)
964{
965 uint32_t ret_val;
966
967 switch (auth_type) {
968 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
969 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
970 break;
971 case eCSR_AUTH_TYPE_SHARED_KEY:
972 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
973 break;
974 case eCSR_AUTH_TYPE_WPA:
975 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
976 break;
977 case eCSR_AUTH_TYPE_WPA_PSK:
978 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
979 break;
980 case eCSR_AUTH_TYPE_AUTOSWITCH:
981 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
982 break;
983 case eCSR_AUTH_TYPE_WPA_NONE:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
985 break;
986 case eCSR_AUTH_TYPE_RSN:
987 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
988 break;
989 case eCSR_AUTH_TYPE_RSN_PSK:
990 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
991 break;
992 case eCSR_AUTH_TYPE_FT_RSN:
993 ret_val = QCA_WLAN_AUTH_TYPE_FT;
994 break;
995 case eCSR_AUTH_TYPE_FT_RSN_PSK:
996 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
997 break;
998 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
999 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1000 break;
1001 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1002 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1003 break;
1004#ifdef FEATURE_WLAN_ESE
1005 case eCSR_AUTH_TYPE_CCKM_WPA:
1006 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1007 break;
1008 case eCSR_AUTH_TYPE_CCKM_RSN:
1009 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1010 break;
1011#endif
1012 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1013 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1014 break;
1015 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1016 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1017 break;
1018 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1019 case eCSR_AUTH_TYPE_FAILED:
1020 case eCSR_AUTH_TYPE_NONE:
1021 default:
1022 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1023 break;
1024 }
1025 return ret_val;
1026}
1027
1028/**
1029 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1030 * vendor command
1031 * @dot11mode: dot11mode
1032 *
1033 * Return: Success(0) or reason code for failure
1034 */
1035static int hdd_convert_dot11mode(uint32_t dot11mode)
1036{
1037 uint32_t ret_val;
1038
1039 switch (dot11mode) {
1040 case eCSR_CFG_DOT11_MODE_11A:
1041 ret_val = QCA_WLAN_802_11_MODE_11A;
1042 break;
1043 case eCSR_CFG_DOT11_MODE_11B:
1044 ret_val = QCA_WLAN_802_11_MODE_11B;
1045 break;
1046 case eCSR_CFG_DOT11_MODE_11G:
1047 ret_val = QCA_WLAN_802_11_MODE_11G;
1048 break;
1049 case eCSR_CFG_DOT11_MODE_11N:
1050 ret_val = QCA_WLAN_802_11_MODE_11N;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11AC:
1053 ret_val = QCA_WLAN_802_11_MODE_11AC;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_AUTO:
1056 case eCSR_CFG_DOT11_MODE_ABG:
1057 default:
1058 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1059 }
1060 return ret_val;
1061}
1062
1063/**
1064 * hdd_add_tx_bitrate() - add tx bitrate attribute
1065 * @skb: pointer to sk buff
1066 * @hdd_sta_ctx: pointer to hdd station context
1067 * @idx: attribute index
1068 *
1069 * Return: Success(0) or reason code for failure
1070 */
1071static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1072 hdd_station_ctx_t *hdd_sta_ctx,
1073 int idx)
1074{
1075 struct nlattr *nla_attr;
1076 uint32_t bitrate, bitrate_compat;
1077
1078 nla_attr = nla_nest_start(skb, idx);
1079 if (!nla_attr)
1080 goto fail;
1081 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301082 bitrate = cfg80211_calculate_bitrate(
1083 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301084
1085 /* report 16-bit bitrate only if we can */
1086 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1087 if (bitrate > 0 &&
1088 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1090 goto fail;
1091 }
1092 if (bitrate_compat > 0 &&
1093 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1095 goto fail;
1096 }
1097 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301098 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 nla_nest_end(skb, nla_attr);
1103 return 0;
1104fail:
1105 return -EINVAL;
1106}
1107
1108/**
1109 * hdd_add_sta_info() - add station info attribute
1110 * @skb: pointer to sk buff
1111 * @hdd_sta_ctx: pointer to hdd station context
1112 * @idx: attribute index
1113 *
1114 * Return: Success(0) or reason code for failure
1115 */
1116static int32_t hdd_add_sta_info(struct sk_buff *skb,
1117 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1118{
1119 struct nlattr *nla_attr;
1120
1121 nla_attr = nla_nest_start(skb, idx);
1122 if (!nla_attr)
1123 goto fail;
1124 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301125 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1127 goto fail;
1128 }
1129 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1130 goto fail;
1131 nla_nest_end(skb, nla_attr);
1132 return 0;
1133fail:
1134 return -EINVAL;
1135}
1136
1137/**
1138 * hdd_add_survey_info() - add survey info attribute
1139 * @skb: pointer to sk buff
1140 * @hdd_sta_ctx: pointer to hdd station context
1141 * @idx: attribute index
1142 *
1143 * Return: Success(0) or reason code for failure
1144 */
1145static int32_t hdd_add_survey_info(struct sk_buff *skb,
1146 hdd_station_ctx_t *hdd_sta_ctx,
1147 int idx)
1148{
1149 struct nlattr *nla_attr;
1150
1151 nla_attr = nla_nest_start(skb, idx);
1152 if (!nla_attr)
1153 goto fail;
1154 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301155 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301156 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301157 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1159 goto fail;
1160 }
1161 nla_nest_end(skb, nla_attr);
1162 return 0;
1163fail:
1164 return -EINVAL;
1165}
1166
1167/**
1168 * hdd_add_link_standard_info() - add link info attribute
1169 * @skb: pointer to sk buff
1170 * @hdd_sta_ctx: pointer to hdd station context
1171 * @idx: attribute index
1172 *
1173 * Return: Success(0) or reason code for failure
1174 */
1175static int32_t
1176hdd_add_link_standard_info(struct sk_buff *skb,
1177 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1178{
1179 struct nlattr *nla_attr;
1180
1181 nla_attr = nla_nest_start(skb, idx);
1182 if (!nla_attr)
1183 goto fail;
1184 if (nla_put(skb,
1185 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301186 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1187 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1189 goto fail;
1190 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301191 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1192 hdd_sta_ctx->cache_conn_info.bssId))
1193 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301194 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1195 goto fail;
1196 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1197 goto fail;
1198 nla_nest_end(skb, nla_attr);
1199 return 0;
1200fail:
1201 return -EINVAL;
1202}
1203
1204/**
1205 * hdd_add_ap_standard_info() - add ap info attribute
1206 * @skb: pointer to sk buff
1207 * @hdd_sta_ctx: pointer to hdd station context
1208 * @idx: attribute index
1209 *
1210 * Return: Success(0) or reason code for failure
1211 */
1212static int32_t
1213hdd_add_ap_standard_info(struct sk_buff *skb,
1214 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1215{
1216 struct nlattr *nla_attr;
1217
1218 nla_attr = nla_nest_start(skb, idx);
1219 if (!nla_attr)
1220 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301221 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301222 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301223 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1224 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1226 goto fail;
1227 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301228 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301229 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1231 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1233 goto fail;
1234 }
1235 nla_nest_end(skb, nla_attr);
1236 return 0;
1237fail:
1238 return -EINVAL;
1239}
1240
1241/**
1242 * hdd_get_station_info() - send BSS information to supplicant
1243 * @hdd_ctx: pointer to hdd context
1244 * @adapter: pointer to adapter
1245 *
1246 * Return: 0 if success else error status
1247 */
1248static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1249 hdd_adapter_t *adapter)
1250{
1251 struct sk_buff *skb = NULL;
1252 uint8_t *tmp_hs20 = NULL;
1253 uint32_t nl_buf_len;
1254 hdd_station_ctx_t *hdd_sta_ctx;
1255
1256 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1257
1258 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301259
1260 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1261 VOS_MAC_ADDR_SIZE +
1262 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1263 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1264 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301265 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301266 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1267 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1268 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1269 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1270 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1272 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1273 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1274 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1275 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1276 cache_conn_info.hs20vendor_ie);
1277 nl_buf_len +=
1278 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301279 1);
1280 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1284 nl_buf_len +=
1285 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301286
1287
1288 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1289 if (!skb) {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1291 __func__, __LINE__);
1292 return -ENOMEM;
1293 }
1294
1295 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1296 LINK_INFO_STANDARD_NL80211_ATTR)) {
1297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1298 goto fail;
1299 }
1300 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1301 AP_INFO_STANDARD_NL80211_ATTR)) {
1302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1303 goto fail;
1304 }
1305 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301306 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301307 nla_put_u32(skb, INFO_AKM,
1308 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301309 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301310 nla_put_u32(skb, WLAN802_11_MODE,
1311 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301312 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1319 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1321 goto fail;
1322 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 (sizeof(hdd_sta_ctx->
1326 cache_conn_info.vht_operation)),
1327 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1329 goto fail;
1330 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301331 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301332 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1334 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1336 goto fail;
1337 }
1338
1339 return cfg80211_vendor_cmd_reply(skb);
1340fail:
1341 if (skb)
1342 kfree_skb(skb);
1343 return -EINVAL;
1344}
1345
1346/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301347 * hdd_add_survey_info_sap_get_len - get data length used in
1348 * hdd_add_survey_info_sap()
1349 *
1350 * This function calculates the data length used in hdd_add_survey_info_sap()
1351 *
1352 * Return: total data length used in hdd_add_survey_info_sap()
1353 */
1354static uint32_t hdd_add_survey_info_sap_get_len(void)
1355{
1356 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1357}
1358
1359/**
1360 * hdd_add_survey_info - add survey info attribute
1361 * @skb: pointer to response skb buffer
1362 * @stainfo: station information
1363 * @idx: attribute type index for nla_next_start()
1364 *
1365 * This function adds survey info attribute to response skb buffer
1366 *
1367 * Return : 0 on success and errno on failure
1368 */
1369static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1370 struct hdd_cache_sta_info *stainfo,
1371 int idx)
1372{
1373 struct nlattr *nla_attr;
1374
1375 nla_attr = nla_nest_start(skb, idx);
1376 if (!nla_attr)
1377 goto fail;
1378 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1379 stainfo->freq)) {
1380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1381 FL("put fail"));
1382 goto fail;
1383 }
1384 nla_nest_end(skb, nla_attr);
1385 return 0;
1386fail:
1387 return -EINVAL;
1388}
1389
1390/**
1391 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1392 * hdd_add_tx_bitrate_sap()
1393 *
1394 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1395 *
1396 * Return: total data length used in hdd_add_tx_bitrate_sap()
1397 */
1398static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1399{
1400 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1401}
1402
1403/**
1404 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1405 * @skb: pointer to response skb buffer
1406 * @stainfo: station information
1407 * @idx: attribute type index for nla_next_start()
1408 *
1409 * This function adds vht nss attribute to response skb buffer
1410 *
1411 * Return : 0 on success and errno on failure
1412 */
1413static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1414 struct hdd_cache_sta_info *stainfo,
1415 int idx)
1416{
1417 struct nlattr *nla_attr;
1418
1419 nla_attr = nla_nest_start(skb, idx);
1420 if (!nla_attr)
1421 goto fail;
1422
1423 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1424 stainfo->nss)) {
1425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1426 FL("put fail"));
1427 goto fail;
1428 }
1429 nla_nest_end(skb, nla_attr);
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435/**
1436 * hdd_add_sta_info_sap_get_len - get data length used in
1437 * hdd_add_sta_info_sap()
1438 *
1439 * This function calculates the data length used in hdd_add_sta_info_sap()
1440 *
1441 * Return: total data length used in hdd_add_sta_info_sap()
1442 */
1443static uint32_t hdd_add_sta_info_sap_get_len(void)
1444{
1445 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1446 hdd_add_tx_bitrate_sap_get_len());
1447}
1448
1449/**
1450 * hdd_add_sta_info_sap - add sta signal info attribute
1451 * @skb: pointer to response skb buffer
1452 * @rssi: peer rssi value
1453 * @stainfo: station information
1454 * @idx: attribute type index for nla_next_start()
1455 *
1456 * This function adds sta signal attribute to response skb buffer
1457 *
1458 * Return : 0 on success and errno on failure
1459 */
1460static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1461 struct hdd_cache_sta_info *stainfo, int idx)
1462{
1463 struct nlattr *nla_attr;
1464
1465 nla_attr = nla_nest_start(skb, idx);
1466 if (!nla_attr)
1467 goto fail;
1468
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301469 /* upperlayer expects positive rssi value */
1470 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1472 FL("put fail"));
1473 goto fail;
1474 }
1475 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1477 FL("put fail"));
1478 goto fail;
1479 }
1480
1481 nla_nest_end(skb, nla_attr);
1482 return 0;
1483fail:
1484 return -EINVAL;
1485}
1486
1487/**
1488 * hdd_add_link_standard_info_sap_get_len - get data length used in
1489 * hdd_add_link_standard_info_sap()
1490 *
1491 * This function calculates the data length used in
1492 * hdd_add_link_standard_info_sap()
1493 *
1494 * Return: total data length used in hdd_add_link_standard_info_sap()
1495 */
1496static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1497{
1498 return ((NLA_HDRLEN) +
1499 hdd_add_survey_info_sap_get_len() +
1500 hdd_add_sta_info_sap_get_len() +
1501 (sizeof(uint32_t) + NLA_HDRLEN));
1502}
1503
1504/**
1505 * hdd_add_link_standard_info_sap - add add link info attribut
1506 * @skb: pointer to response skb buffer
1507 * @stainfo: station information
1508 * @idx: attribute type index for nla_next_start()
1509 *
1510 * This function adds link info attribut to response skb buffer
1511 *
1512 * Return : 0 on success and errno on failure
1513 */
1514static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1515 struct hdd_cache_sta_info *stainfo,
1516 int idx)
1517{
1518 struct nlattr *nla_attr;
1519
1520 nla_attr = nla_nest_start(skb, idx);
1521 if (!nla_attr)
1522 goto fail;
1523 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1524 goto fail;
1525 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1526 goto fail;
1527
1528 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 FL("put fail"));
1531 goto fail;
1532 }
1533
1534 nla_nest_end(skb, nla_attr);
1535 return 0;
1536fail:
1537 return -EINVAL;
1538}
1539
1540/**
1541 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1542 * hdd_add_ap_standard_info_sap()
1543 * @stainfo: station information
1544 *
1545 * This function calculates the data length used in
1546 * hdd_add_ap_standard_info_sap()
1547 *
1548 * Return: total data length used in hdd_add_ap_standard_info_sap()
1549 */
1550static uint32_t hdd_add_ap_standard_info_sap_get_len(
1551 struct hdd_cache_sta_info *stainfo)
1552{
1553 uint32_t len;
1554
1555 len = NLA_HDRLEN;
1556 if (stainfo->vht_present)
1557 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1558 if (stainfo->ht_present)
1559 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1560
1561 return len;
1562}
1563
1564/**
1565 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1566 * @skb: pointer to response skb buffer
1567 * @stainfo: station information
1568 * @idx: attribute type index for nla_next_start()
1569 *
1570 * This function adds HT and VHT info attributes to response skb buffer
1571 *
1572 * Return : 0 on success and errno on failure
1573 */
1574static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1575 struct hdd_cache_sta_info *stainfo,
1576 int idx)
1577{
1578 struct nlattr *nla_attr;
1579
1580 nla_attr = nla_nest_start(skb, idx);
1581 if (!nla_attr)
1582 goto fail;
1583
1584 if (stainfo->vht_present) {
1585 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1586 sizeof(stainfo->vht_caps),
1587 &stainfo->vht_caps)) {
1588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1589 FL("put fail"));
1590 goto fail;
1591 }
1592 }
1593 if (stainfo->ht_present) {
1594 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1595 sizeof(stainfo->ht_caps),
1596 &stainfo->ht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 nla_nest_end(skb, nla_attr);
1603 return 0;
1604fail:
1605 return -EINVAL;
1606}
1607
1608/**
1609 * hdd_decode_ch_width - decode channel band width based
1610 * @ch_width: encoded enum value holding channel band width
1611 *
1612 * This function decodes channel band width from the given encoded enum value.
1613 *
1614 * Returns: decoded channel band width.
1615 */
1616static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1617{
1618 switch (ch_width) {
1619 case 0:
1620 return 20;
1621 case 1:
1622 return 40;
1623 case 2:
1624 return 80;
1625 default:
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 "invalid enum: %d", ch_width);
1628 return 20;
1629 }
1630}
1631
1632/**
1633 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1634 * @hdd_ctx: hdd context
1635 * @adapter: hostapd interface
1636 * @mac_addr: mac address of requested peer
1637 *
1638 * This function collect and indicate the cached(deleted) peer's info
1639 *
1640 * Return: 0 on success, otherwise error value
1641 */
1642static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1643 hdd_adapter_t *adapter,
1644 v_MACADDR_t mac_addr)
1645{
1646 struct hdd_cache_sta_info *stainfo;
1647 struct sk_buff *skb = NULL;
1648 uint32_t nl_buf_len;
1649 uint8_t cw;
1650 ptSapContext sap_ctx;
1651 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1652
1653 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1654 if(sap_ctx == NULL){
1655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1656 FL("psapCtx is NULL"));
1657 return -ENOENT;
1658 }
1659
1660 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1661 mac_addr.bytes);
1662 if (!stainfo) {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "peer " MAC_ADDRESS_STR " not found",
1665 MAC_ADDR_ARRAY(mac_addr.bytes));
1666 return -EINVAL;
1667 }
1668 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1670 "peer " MAC_ADDRESS_STR " is in connected state",
1671 MAC_ADDR_ARRAY(mac_addr.bytes));
1672 return -EINVAL;
1673 }
1674
1675
1676 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1677 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1678 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1679 (sizeof(cw) + NLA_HDRLEN) +
1680 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1681
1682 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1683 if (!skb) {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1685 return -ENOMEM;
1686 }
1687
1688 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1689 LINK_INFO_STANDARD_NL80211_ATTR)) {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1691 goto fail;
1692 }
1693
1694 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1695 AP_INFO_STANDARD_NL80211_ATTR)) {
1696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1697 goto fail;
1698 }
1699
1700 /* upper layer expects decoded channel BW */
1701 cw = hdd_decode_ch_width(stainfo->ch_width);
1702 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1703 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1705 goto fail;
1706 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301707 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1709 goto fail;
1710 }
1711
1712 vos_mem_zero(stainfo, sizeof(*stainfo));
1713
1714 return cfg80211_vendor_cmd_reply(skb);
1715fail:
1716 if (skb)
1717 kfree_skb(skb);
1718
1719 return -EINVAL;
1720}
1721
1722/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301723 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1724 * @wiphy: corestack handler
1725 * @wdev: wireless device
1726 * @data: data
1727 * @data_len: data length
1728 *
1729 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1730 * Validate cmd attributes and send the station info to upper layers.
1731 *
1732 * Return: Success(0) or reason code for failure
1733 */
1734static int32_t
1735__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1737 const void *data,
1738 int data_len)
1739{
1740 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1741 struct net_device *dev = wdev->netdev;
1742 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1743 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1744 int32_t status;
1745
1746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1747 if (VOS_FTM_MODE == hdd_get_conparam()) {
1748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1749 status = -EPERM;
1750 goto out;
1751 }
1752
1753 status = wlan_hdd_validate_context(hdd_ctx);
1754 if (0 != status)
1755 goto out;
1756
1757
1758 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1759 data, data_len, NULL);
1760 if (status) {
1761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1762 goto out;
1763 }
1764
1765 /* Parse and fetch Command Type*/
1766 if (tb[STATION_INFO]) {
1767 status = hdd_get_station_info(hdd_ctx, adapter);
1768 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1769 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301770 } else if (tb[STATION_REMOTE]) {
1771 v_MACADDR_t mac_addr;
1772
1773 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1774 adapter->device_mode != WLAN_HDD_P2P_GO) {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1776 adapter->device_mode);
1777 status = -EINVAL;
1778 goto out;
1779 }
1780
1781 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1782 VOS_MAC_ADDRESS_LEN);
1783
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1785 MAC_ADDR_ARRAY(mac_addr.bytes));
1786
1787 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1788 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301789 } else {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1791 status = -EINVAL;
1792 goto out;
1793 }
1794 EXIT();
1795out:
1796 return status;
1797}
1798
1799/**
1800 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1801 * @wiphy: corestack handler
1802 * @wdev: wireless device
1803 * @data: data
1804 * @data_len: data length
1805 *
1806 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1807 * Validate cmd attributes and send the station info to upper layers.
1808 *
1809 * Return: Success(0) or reason code for failure
1810 */
1811static int32_t
1812hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
1814 const void *data,
1815 int data_len)
1816{
1817 int ret;
1818
1819 vos_ssr_protect(__func__);
1820 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1821 vos_ssr_unprotect(__func__);
1822
1823 return ret;
1824}
1825
1826/*
1827 * undef short names defined for get station command
1828 * used by __wlan_hdd_cfg80211_get_station_cmd()
1829 */
1830#undef STATION_INVALID
1831#undef STATION_INFO
1832#undef STATION_ASSOC_FAIL_REASON
1833#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1836
1837static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1838 struct sk_buff *vendor_event)
1839{
1840 if (nla_put_u8(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1842 stats->rate.preamble) ||
1843 nla_put_u8(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1845 stats->rate.nss) ||
1846 nla_put_u8(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1848 stats->rate.bw) ||
1849 nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1851 stats->rate.rateMcsIdx) ||
1852 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1853 stats->rate.bitrate ) ||
1854 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1855 stats->txMpdu ) ||
1856 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1857 stats->rxMpdu ) ||
1858 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1859 stats->mpduLost ) ||
1860 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1861 stats->retries) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1864 stats->retriesShort ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1867 stats->retriesLong))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1871 return FALSE;
1872 }
1873 return TRUE;
1874}
1875
1876static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1877 struct sk_buff *vendor_event)
1878{
1879 u32 i = 0;
1880 struct nlattr *rateInfo;
1881 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1882 stats->type) ||
1883 nla_put(vendor_event,
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1885 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1886 nla_put_u32(vendor_event,
1887 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1888 stats->capabilities) ||
1889 nla_put_u32(vendor_event,
1890 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1891 stats->numRate))
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR,
1894 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1895 goto error;
1896 }
1897
1898 rateInfo = nla_nest_start(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301900 if(!rateInfo)
1901 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 for (i = 0; i < stats->numRate; i++)
1903 {
1904 struct nlattr *rates;
1905 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1906 stats->rateStats +
1907 (i * sizeof(tSirWifiRateStat)));
1908 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rates)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911
1912 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1913 {
1914 hddLog(VOS_TRACE_LEVEL_ERROR,
1915 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1916 return FALSE;
1917 }
1918 nla_nest_end(vendor_event, rates);
1919 }
1920 nla_nest_end(vendor_event, rateInfo);
1921
1922 return TRUE;
1923error:
1924 return FALSE;
1925}
1926
1927static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1928 struct sk_buff *vendor_event)
1929{
1930 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1931 stats->ac ) ||
1932 nla_put_u32(vendor_event,
1933 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1934 stats->txMpdu ) ||
1935 nla_put_u32(vendor_event,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1937 stats->rxMpdu ) ||
1938 nla_put_u32(vendor_event,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1940 stats->txMcast ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1943 stats->rxMcast ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1946 stats->rxAmpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1949 stats->txAmpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1952 stats->mpduLost )||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1955 stats->retries ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1958 stats->retriesShort ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1961 stats->retriesLong ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1964 stats->contentionTimeMin ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1967 stats->contentionTimeMax ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1970 stats->contentionTimeAvg ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1973 stats->contentionNumSamples ))
1974 {
1975 hddLog(VOS_TRACE_LEVEL_ERROR,
1976 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1977 return FALSE;
1978 }
1979 return TRUE;
1980}
1981
1982static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1983 struct sk_buff *vendor_event)
1984{
Dino Myclec8f3f332014-07-21 16:48:27 +05301985 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301986 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1987 nla_put(vendor_event,
1988 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1989 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1990 nla_put_u32(vendor_event,
1991 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1992 stats->state ) ||
1993 nla_put_u32(vendor_event,
1994 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1995 stats->roaming ) ||
1996 nla_put_u32(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1998 stats->capabilities ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2001 strlen(stats->ssid), stats->ssid) ||
2002 nla_put(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2004 WNI_CFG_BSSID_LEN, stats->bssid) ||
2005 nla_put(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2007 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2010 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2011 )
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2015 return FALSE;
2016 }
2017 return TRUE;
2018}
2019
Dino Mycle3b9536d2014-07-09 22:05:24 +05302020static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2021 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022 struct sk_buff *vendor_event)
2023{
2024 int i = 0;
2025 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302026 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2027 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302028 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 if (FALSE == put_wifi_interface_info(
2031 &pWifiIfaceStat->info,
2032 vendor_event))
2033 {
2034 hddLog(VOS_TRACE_LEVEL_ERROR,
2035 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2036 return FALSE;
2037
2038 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2040 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2041 if (NULL == pWifiIfaceStatTL)
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2044 return FALSE;
2045 }
2046
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302047 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2048 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2049 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2051
2052 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302056
2057 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2058 {
2059 if (VOS_STATUS_SUCCESS ==
2060 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2061 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2062 {
2063 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2064 * obtained from TL structure
2065 */
2066
2067 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2068 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302069 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2070
Srinivas Dasari98947432014-11-07 19:41:24 +05302071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2072 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2074 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2076 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2078 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097 }
2098 else
2099 {
2100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2101 }
2102
Dino Mycle3b9536d2014-07-09 22:05:24 +05302103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2104 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2106 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2108 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2109 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2111 }
2112 else
2113 {
2114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2115 }
2116
2117
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118
2119 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302120 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2121 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2122 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2124 pWifiIfaceStat->beaconRx) ||
2125 nla_put_u32(vendor_event,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2127 pWifiIfaceStat->mgmtRx) ||
2128 nla_put_u32(vendor_event,
2129 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2130 pWifiIfaceStat->mgmtActionRx) ||
2131 nla_put_u32(vendor_event,
2132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2133 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302134 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2136 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302137 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2139 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302140 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2142 pWifiIfaceStat->rssiAck))
2143 {
2144 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302145 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2146 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 return FALSE;
2148 }
2149
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302150#ifdef FEATURE_EXT_LL_STAT
2151 /*
2152 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2153 * then host should send Leaky AP stats to upper layer,
2154 * otherwise no need to send these stats.
2155 */
2156 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2157 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2158 )
2159 {
2160 hddLog(VOS_TRACE_LEVEL_INFO,
2161 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2162 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2163 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2164 pWifiIfaceStat->leakyApStat.rx_leak_window,
2165 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2166 if (nla_put_u32(vendor_event,
2167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2168 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2169 nla_put_u32(vendor_event,
2170 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2171 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2172 nla_put_u32(vendor_event,
2173 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302175 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2178 {
2179 hddLog(VOS_TRACE_LEVEL_ERROR,
2180 FL("EXT_LL_STAT put fail"));
2181 vos_mem_free(pWifiIfaceStatTL);
2182 return FALSE;
2183 }
2184 }
2185#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302186 wmmInfo = nla_nest_start(vendor_event,
2187 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302188 if(!wmmInfo)
2189 {
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 for (i = 0; i < WIFI_AC_MAX; i++)
2194 {
2195 struct nlattr *wmmStats;
2196 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmStats)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 if (FALSE == put_wifi_wmm_ac_stat(
2203 &pWifiIfaceStat->AccessclassStats[i],
2204 vendor_event))
2205 {
2206 hddLog(VOS_TRACE_LEVEL_ERROR,
2207 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302208 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 return FALSE;
2210 }
2211
2212 nla_nest_end(vendor_event, wmmStats);
2213 }
2214 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302215 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302216 return TRUE;
2217}
2218
2219static tSirWifiInterfaceMode
2220 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2221{
2222 switch (deviceMode)
2223 {
2224 case WLAN_HDD_INFRA_STATION:
2225 return WIFI_INTERFACE_STA;
2226 case WLAN_HDD_SOFTAP:
2227 return WIFI_INTERFACE_SOFTAP;
2228 case WLAN_HDD_P2P_CLIENT:
2229 return WIFI_INTERFACE_P2P_CLIENT;
2230 case WLAN_HDD_P2P_GO:
2231 return WIFI_INTERFACE_P2P_GO;
2232 case WLAN_HDD_IBSS:
2233 return WIFI_INTERFACE_IBSS;
2234 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302235 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 }
2237}
2238
2239static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2240 tpSirWifiInterfaceInfo pInfo)
2241{
2242 v_U8_t *staMac = NULL;
2243 hdd_station_ctx_t *pHddStaCtx;
2244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2245 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2246
2247 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2248
2249 vos_mem_copy(pInfo->macAddr,
2250 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2251
2252 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2253 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2254 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2255 {
2256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2257 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2258 {
2259 pInfo->state = WIFI_DISCONNECTED;
2260 }
2261 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR,
2264 "%s: Session ID %d, Connection is in progress", __func__,
2265 pAdapter->sessionId);
2266 pInfo->state = WIFI_ASSOCIATING;
2267 }
2268 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2269 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2270 {
2271 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: client " MAC_ADDRESS_STR
2274 " is in the middle of WPS/EAPOL exchange.", __func__,
2275 MAC_ADDR_ARRAY(staMac));
2276 pInfo->state = WIFI_AUTHENTICATING;
2277 }
2278 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2279 {
2280 pInfo->state = WIFI_ASSOCIATED;
2281 vos_mem_copy(pInfo->bssid,
2282 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2283 vos_mem_copy(pInfo->ssid,
2284 pHddStaCtx->conn_info.SSID.SSID.ssId,
2285 pHddStaCtx->conn_info.SSID.SSID.length);
2286 //NULL Terminate the string.
2287 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2288 }
2289 }
2290 vos_mem_copy(pInfo->countryStr,
2291 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2292
2293 vos_mem_copy(pInfo->apCountryStr,
2294 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2295
2296 return TRUE;
2297}
2298
2299/*
2300 * hdd_link_layer_process_peer_stats () - This function is called after
2301 * receiving Link Layer Peer statistics from FW.This function converts
2302 * the firmware data to the NL data and sends the same to the kernel/upper
2303 * layers.
2304 */
2305static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2306 v_VOID_t *pData)
2307{
2308 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309 tpSirWifiPeerStat pWifiPeerStat;
2310 tpSirWifiPeerInfo pWifiPeerInfo;
2311 struct nlattr *peerInfo;
2312 struct sk_buff *vendor_event;
2313 int status, i;
2314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302315 ENTER();
2316
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317 status = wlan_hdd_validate_context(pHddCtx);
2318 if (0 != status)
2319 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 return;
2321 }
2322
2323 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2324
2325 hddLog(VOS_TRACE_LEVEL_INFO,
2326 "LL_STATS_PEER_ALL : numPeers %u",
2327 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 /*
2329 * Allocate a size of 4096 for the peer stats comprising
2330 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2331 * sizeof (tSirWifiRateStat).Each field is put with an
2332 * NL attribute.The size of 4096 is considered assuming
2333 * that number of rates shall not exceed beyond 50 with
2334 * the sizeof (tSirWifiRateStat) being 32.
2335 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302336 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2337 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 if (!vendor_event)
2339 {
2340 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302341 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302342 __func__);
2343 return;
2344 }
2345 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2347 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2348 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302349 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2350 pWifiPeerStat->numPeers))
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
2353 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2354 kfree_skb(vendor_event);
2355 return;
2356 }
2357
2358 peerInfo = nla_nest_start(vendor_event,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302360 if(!peerInfo)
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2364 __func__);
2365 kfree_skb(vendor_event);
2366 return;
2367 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368
2369 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2370 pWifiPeerStat->peerInfo);
2371
2372 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2373 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302374 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302375 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302377 if(!peers)
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR,
2380 "%s: peer stats put fail",
2381 __func__);
2382 kfree_skb(vendor_event);
2383 return;
2384 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 if (FALSE == put_wifi_peer_info(
2386 pWifiPeerInfo, vendor_event))
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: put_wifi_peer_info put fail", __func__);
2390 kfree_skb(vendor_event);
2391 return;
2392 }
2393
2394 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2395 pWifiPeerStat->peerInfo +
2396 (i * sizeof(tSirWifiPeerInfo)) +
2397 (numRate * sizeof (tSirWifiRateStat)));
2398 nla_nest_end(vendor_event, peers);
2399 }
2400 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302401 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403}
2404
2405/*
2406 * hdd_link_layer_process_iface_stats () - This function is called after
2407 * receiving Link Layer Interface statistics from FW.This function converts
2408 * the firmware data to the NL data and sends the same to the kernel/upper
2409 * layers.
2410 */
2411static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2412 v_VOID_t *pData)
2413{
2414 tpSirWifiIfaceStat pWifiIfaceStat;
2415 struct sk_buff *vendor_event;
2416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2417 int status;
2418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 ENTER();
2420
Sunil Duttc69bccb2014-05-26 21:30:20 +05302421 status = wlan_hdd_validate_context(pHddCtx);
2422 if (0 != status)
2423 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 return;
2425 }
2426 /*
2427 * Allocate a size of 4096 for the interface stats comprising
2428 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2429 * assuming that all these fit with in the limit.Please take
2430 * a call on the limit based on the data requirements on
2431 * interface statistics.
2432 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2434 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 if (!vendor_event)
2436 {
2437 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302438 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302439 return;
2440 }
2441
2442 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2443
Dino Mycle3b9536d2014-07-09 22:05:24 +05302444
2445 if (FALSE == hdd_get_interface_info( pAdapter,
2446 &pWifiIfaceStat->info))
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR,
2449 FL("hdd_get_interface_info get fail") );
2450 kfree_skb(vendor_event);
2451 return;
2452 }
2453
2454 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2455 vendor_event))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("put_wifi_iface_stats fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
Sunil Duttc69bccb2014-05-26 21:30:20 +05302463 hddLog(VOS_TRACE_LEVEL_INFO,
2464 "WMI_LINK_STATS_IFACE Data");
2465
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302466 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467
2468 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302469}
2470
2471/*
2472 * hdd_link_layer_process_radio_stats () - This function is called after
2473 * receiving Link Layer Radio statistics from FW.This function converts
2474 * the firmware data to the NL data and sends the same to the kernel/upper
2475 * layers.
2476 */
2477static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2478 v_VOID_t *pData)
2479{
2480 int status, i;
2481 tpSirWifiRadioStat pWifiRadioStat;
2482 tpSirWifiChannelStats pWifiChannelStats;
2483 struct sk_buff *vendor_event;
2484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2485 struct nlattr *chList;
2486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302487 ENTER();
2488
Sunil Duttc69bccb2014-05-26 21:30:20 +05302489 status = wlan_hdd_validate_context(pHddCtx);
2490 if (0 != status)
2491 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302492 return;
2493 }
2494 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2495
2496 hddLog(VOS_TRACE_LEVEL_INFO,
2497 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302498 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 " radio is %d onTime is %u "
2500 " txTime is %u rxTime is %u "
2501 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302503 " onTimePnoScan is %u onTimeHs20 is %u "
2504 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302505 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302506 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2507 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2508 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 pWifiRadioStat->onTimeRoamScan,
2511 pWifiRadioStat->onTimePnoScan,
2512 pWifiRadioStat->onTimeHs20,
2513 pWifiRadioStat->numChannels);
2514 /*
2515 * Allocate a size of 4096 for the Radio stats comprising
2516 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2517 * (tSirWifiChannelStats).Each channel data is put with an
2518 * NL attribute.The size of 4096 is considered assuming that
2519 * number of channels shall not exceed beyond 60 with the
2520 * sizeof (tSirWifiChannelStats) being 24 bytes.
2521 */
2522
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302523 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2524 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302525 if (!vendor_event)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302528 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529 return;
2530 }
2531
2532 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2534 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2535 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2537 pWifiRadioStat->radio) ||
2538 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302539 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2540 NUM_RADIOS) ||
2541 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2543 pWifiRadioStat->onTime) ||
2544 nla_put_u32(vendor_event,
2545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2546 pWifiRadioStat->txTime) ||
2547 nla_put_u32(vendor_event,
2548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2549 pWifiRadioStat->rxTime) ||
2550 nla_put_u32(vendor_event,
2551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2552 pWifiRadioStat->onTimeScan) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2555 pWifiRadioStat->onTimeNbd) ||
2556 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2558 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2561 pWifiRadioStat->onTimeRoamScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2564 pWifiRadioStat->onTimePnoScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2567 pWifiRadioStat->onTimeHs20) ||
2568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2570 pWifiRadioStat->numChannels))
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR,
2573 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2574 kfree_skb(vendor_event);
2575 return ;
2576 }
2577
2578 chList = nla_nest_start(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302580 if(!chList)
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2584 __func__);
2585 kfree_skb(vendor_event);
2586 return;
2587 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302588 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2589 {
2590 struct nlattr *chInfo;
2591
2592 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2593 pWifiRadioStat->channels +
2594 (i * sizeof(tSirWifiChannelStats)));
2595
Sunil Duttc69bccb2014-05-26 21:30:20 +05302596 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302597 if(!chInfo)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 "%s: failed to put chInfo",
2601 __func__);
2602 kfree_skb(vendor_event);
2603 return;
2604 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605
2606 if (nla_put_u32(vendor_event,
2607 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2608 pWifiChannelStats->channel.width) ||
2609 nla_put_u32(vendor_event,
2610 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2611 pWifiChannelStats->channel.centerFreq) ||
2612 nla_put_u32(vendor_event,
2613 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2614 pWifiChannelStats->channel.centerFreq0) ||
2615 nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2617 pWifiChannelStats->channel.centerFreq1) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2620 pWifiChannelStats->onTime) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2623 pWifiChannelStats->ccaBusyTime))
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR,
2626 FL("cfg80211_vendor_event_alloc failed") );
2627 kfree_skb(vendor_event);
2628 return ;
2629 }
2630 nla_nest_end(vendor_event, chInfo);
2631 }
2632 nla_nest_end(vendor_event, chList);
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635
2636 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302637 return;
2638}
2639
2640/*
2641 * hdd_link_layer_stats_ind_callback () - This function is called after
2642 * receiving Link Layer indications from FW.This callback converts the firmware
2643 * data to the NL data and send the same to the kernel/upper layers.
2644 */
2645static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2646 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302647 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648{
Dino Mycled3d50022014-07-07 12:58:25 +05302649 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2650 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302651 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302652 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302653 int status;
2654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302655 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658 if (0 != status)
2659 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660 return;
2661 }
2662
Dino Mycled3d50022014-07-07 12:58:25 +05302663 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2664 if (NULL == pAdapter)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR,
2667 FL(" MAC address %pM does not exist with host"),
2668 macAddr);
2669 return;
2670 }
2671
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302673 "%s: Interface: %s LLStats indType: %d", __func__,
2674 pAdapter->dev->name, indType);
2675
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676 switch (indType)
2677 {
2678 case SIR_HAL_LL_STATS_RESULTS_RSP:
2679 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302681 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2682 "respId = %u, moreResultToFollow = %u",
2683 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2684 macAddr, linkLayerStatsResults->respId,
2685 linkLayerStatsResults->moreResultToFollow);
2686
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302687 spin_lock(&hdd_context_lock);
2688 context = &pHddCtx->ll_stats_context;
2689 /* validate response received from target */
2690 if ((context->request_id != linkLayerStatsResults->respId) ||
2691 !(context->request_bitmap & linkLayerStatsResults->paramId))
2692 {
2693 spin_unlock(&hdd_context_lock);
2694 hddLog(LOGE,
2695 FL("Error : Request id %d response id %d request bitmap 0x%x"
2696 "response bitmap 0x%x"),
2697 context->request_id, linkLayerStatsResults->respId,
2698 context->request_bitmap, linkLayerStatsResults->paramId);
2699 return;
2700 }
2701 spin_unlock(&hdd_context_lock);
2702
Sunil Duttc69bccb2014-05-26 21:30:20 +05302703 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2704 {
2705 hdd_link_layer_process_radio_stats(pAdapter,
2706 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302707 spin_lock(&hdd_context_lock);
2708 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2709 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302710 }
2711 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2712 {
2713 hdd_link_layer_process_iface_stats(pAdapter,
2714 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302715 spin_lock(&hdd_context_lock);
2716 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2717 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 }
2719 else if ( linkLayerStatsResults->paramId &
2720 WMI_LINK_STATS_ALL_PEER )
2721 {
2722 hdd_link_layer_process_peer_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_ALL_PEER);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 } /* WMI_LINK_STATS_ALL_PEER */
2728 else
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2732 }
2733
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 /* complete response event if all requests are completed */
2736 if (0 == context->request_bitmap)
2737 complete(&context->response_event);
2738 spin_unlock(&hdd_context_lock);
2739
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 break;
2741 }
2742 default:
2743 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2744 break;
2745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302746
2747 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 return;
2749}
2750
2751const struct
2752nla_policy
2753qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2754{
2755 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2756 { .type = NLA_U32 },
2757 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2758 { .type = NLA_U32 },
2759};
2760
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302761static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2762 struct wireless_dev *wdev,
2763 const void *data,
2764 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302765{
2766 int status;
2767 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302768 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302769 struct net_device *dev = wdev->netdev;
2770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775 status = wlan_hdd_validate_context(pHddCtx);
2776 if (0 != status)
2777 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 return -EINVAL;
2779 }
2780
2781 if (NULL == pAdapter)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR,
2784 FL("HDD adapter is Null"));
2785 return -ENODEV;
2786 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302787 /* check the LLStats Capability */
2788 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2789 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2790 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302791 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302792 FL("Link Layer Statistics not supported by Firmware"));
2793 return -EINVAL;
2794 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795
2796 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2797 (struct nlattr *)data,
2798 data_len, qca_wlan_vendor_ll_set_policy))
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2801 return -EINVAL;
2802 }
2803 if (!tb_vendor
2804 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2807 return -EINVAL;
2808 }
2809 if (!tb_vendor[
2810 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2813 return -EINVAL;
2814 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302816 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302817
Dino Mycledf0a5d92014-07-04 09:41:55 +05302818 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302819 nla_get_u32(
2820 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2821
Dino Mycledf0a5d92014-07-04 09:41:55 +05302822 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302823 nla_get_u32(
2824 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2825
Dino Mycled3d50022014-07-07 12:58:25 +05302826 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2827 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828
2829
2830 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302831 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2832 "Statistics Gathering = %d ",
2833 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2834 linkLayerStatsSetReq.mpduSizeThreshold,
2835 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836
2837 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2838 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302839 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2842 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843 return -EINVAL;
2844
2845 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302846
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302848 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853 }
2854
2855 pAdapter->isLinkLayerStatsSet = 1;
2856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 return 0;
2859}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302860static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2861 struct wireless_dev *wdev,
2862 const void *data,
2863 int data_len)
2864{
2865 int ret = 0;
2866
2867 vos_ssr_protect(__func__);
2868 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2869 vos_ssr_unprotect(__func__);
2870
2871 return ret;
2872}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302873
2874const struct
2875nla_policy
2876qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2877{
2878 /* Unsigned 32bit value provided by the caller issuing the GET stats
2879 * command. When reporting
2880 * the stats results, the driver uses the same value to indicate
2881 * which GET request the results
2882 * correspond to.
2883 */
2884 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2885
2886 /* Unsigned 32bit value . bit mask to identify what statistics are
2887 requested for retrieval */
2888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2889};
2890
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302891static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2892 struct wireless_dev *wdev,
2893 const void *data,
2894 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302896 unsigned long rc;
2897 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2899 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302900 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302901 struct net_device *dev = wdev->netdev;
2902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904 int status;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 status = wlan_hdd_validate_context(pHddCtx);
2909 if (0 != status)
2910 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 return -EINVAL ;
2912 }
2913
2914 if (NULL == pAdapter)
2915 {
2916 hddLog(VOS_TRACE_LEVEL_FATAL,
2917 "%s: HDD adapter is Null", __func__);
2918 return -ENODEV;
2919 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302920
2921 if (pHddStaCtx == NULL)
2922 {
2923 hddLog(VOS_TRACE_LEVEL_FATAL,
2924 "%s: HddStaCtx is Null", __func__);
2925 return -ENODEV;
2926 }
2927
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 /* check the LLStats Capability */
2929 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2930 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2931 {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("Link Layer Statistics not supported by Firmware"));
2934 return -EINVAL;
2935 }
2936
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937
2938 if (!pAdapter->isLinkLayerStatsSet)
2939 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302940 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302941 "%s: isLinkLayerStatsSet : %d",
2942 __func__, pAdapter->isLinkLayerStatsSet);
2943 return -EINVAL;
2944 }
2945
Mukul Sharma10313ba2015-07-29 19:14:39 +05302946 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2947 {
2948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2949 "%s: Roaming in progress, so unable to proceed this request", __func__);
2950 return -EBUSY;
2951 }
2952
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2954 (struct nlattr *)data,
2955 data_len, qca_wlan_vendor_ll_get_policy))
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2958 return -EINVAL;
2959 }
2960
2961 if (!tb_vendor
2962 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2963 {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2965 return -EINVAL;
2966 }
2967
2968 if (!tb_vendor
2969 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2970 {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2972 return -EINVAL;
2973 }
2974
Sunil Duttc69bccb2014-05-26 21:30:20 +05302975
Dino Mycledf0a5d92014-07-04 09:41:55 +05302976 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302977 nla_get_u32( tb_vendor[
2978 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302979 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980 nla_get_u32( tb_vendor[
2981 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2982
Dino Mycled3d50022014-07-07 12:58:25 +05302983 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2984 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
2986 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302987 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2988 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302991 spin_lock(&hdd_context_lock);
2992 context = &pHddCtx->ll_stats_context;
2993 context->request_id = linkLayerStatsGetReq.reqId;
2994 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2995 INIT_COMPLETION(context->response_event);
2996 spin_unlock(&hdd_context_lock);
2997
Sunil Duttc69bccb2014-05-26 21:30:20 +05302998 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3002 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 return -EINVAL;
3004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303005
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303006 rc = wait_for_completion_timeout(&context->response_event,
3007 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3008 if (!rc)
3009 {
3010 hddLog(LOGE,
3011 FL("Target response timed out request id %d request bitmap 0x%x"),
3012 context->request_id, context->request_bitmap);
3013 return -ETIMEDOUT;
3014 }
3015
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303016 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017 return 0;
3018}
3019
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303020static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3021 struct wireless_dev *wdev,
3022 const void *data,
3023 int data_len)
3024{
3025 int ret = 0;
3026
3027 vos_ssr_protect(__func__);
3028 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3029 vos_ssr_unprotect(__func__);
3030
3031 return ret;
3032}
3033
Sunil Duttc69bccb2014-05-26 21:30:20 +05303034const struct
3035nla_policy
3036qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3037{
3038 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3039 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3040 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3041 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3042};
3043
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303044static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3045 struct wireless_dev *wdev,
3046 const void *data,
3047 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303048{
3049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3050 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303051 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 struct net_device *dev = wdev->netdev;
3053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3054 u32 statsClearReqMask;
3055 u8 stopReq;
3056 int status;
3057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303058 ENTER();
3059
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060 status = wlan_hdd_validate_context(pHddCtx);
3061 if (0 != status)
3062 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303063 return -EINVAL;
3064 }
3065
3066 if (NULL == pAdapter)
3067 {
3068 hddLog(VOS_TRACE_LEVEL_FATAL,
3069 "%s: HDD adapter is Null", __func__);
3070 return -ENODEV;
3071 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303072 /* check the LLStats Capability */
3073 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3074 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3075 {
3076 hddLog(VOS_TRACE_LEVEL_ERROR,
3077 FL("Enable LLStats Capability"));
3078 return -EINVAL;
3079 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080
3081 if (!pAdapter->isLinkLayerStatsSet)
3082 {
3083 hddLog(VOS_TRACE_LEVEL_FATAL,
3084 "%s: isLinkLayerStatsSet : %d",
3085 __func__, pAdapter->isLinkLayerStatsSet);
3086 return -EINVAL;
3087 }
3088
3089 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3090 (struct nlattr *)data,
3091 data_len, qca_wlan_vendor_ll_clr_policy))
3092 {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3094 return -EINVAL;
3095 }
3096
3097 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3098
3099 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3102 return -EINVAL;
3103
3104 }
3105
Sunil Duttc69bccb2014-05-26 21:30:20 +05303106
Dino Mycledf0a5d92014-07-04 09:41:55 +05303107 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303108 nla_get_u32(
3109 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3110
Dino Mycledf0a5d92014-07-04 09:41:55 +05303111 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303112 nla_get_u8(
3113 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3114
3115 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117
Dino Mycled3d50022014-07-07 12:58:25 +05303118 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3119 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120
3121 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303122 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3123 "statsClearReqMask = 0x%X, stopReq = %d",
3124 linkLayerStatsClearReq.reqId,
3125 linkLayerStatsClearReq.macAddr,
3126 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303127 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303128
3129 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303130 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303131 {
3132 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303133 hdd_station_ctx_t *pHddStaCtx;
3134
3135 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3136 if (VOS_STATUS_SUCCESS !=
3137 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3138 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3139 {
3140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3141 "WLANTL_ClearInterfaceStats Failed", __func__);
3142 return -EINVAL;
3143 }
3144 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3145 (statsClearReqMask & WIFI_STATS_IFACE)) {
3146 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3147 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3148 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3149 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3150 }
3151
Sunil Duttc69bccb2014-05-26 21:30:20 +05303152 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3153 2 * sizeof(u32) +
3154 NLMSG_HDRLEN);
3155
3156 if (temp_skbuff != NULL)
3157 {
3158
3159 if (nla_put_u32(temp_skbuff,
3160 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3161 statsClearReqMask) ||
3162 nla_put_u32(temp_skbuff,
3163 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3164 stopReq))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3167 kfree_skb(temp_skbuff);
3168 return -EINVAL;
3169 }
3170 /* If the ask is to stop the stats collection as part of clear
3171 * (stopReq = 1) , ensure that no further requests of get
3172 * go to the firmware by having isLinkLayerStatsSet set to 0.
3173 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303174 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303175 * case the firmware is just asked to clear the statistics.
3176 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303177 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303178 pAdapter->isLinkLayerStatsSet = 0;
3179 return cfg80211_vendor_cmd_reply(temp_skbuff);
3180 }
3181 return -ENOMEM;
3182 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303183
3184 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 return -EINVAL;
3186}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303187static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3188 struct wireless_dev *wdev,
3189 const void *data,
3190 int data_len)
3191{
3192 int ret = 0;
3193
3194 vos_ssr_protect(__func__);
3195 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3196 vos_ssr_unprotect(__func__);
3197
3198 return ret;
3199
3200
3201}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303202#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204#ifdef WLAN_FEATURE_EXTSCAN
3205static const struct nla_policy
3206wlan_hdd_extscan_config_policy
3207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3208{
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3210 { .type = NLA_U32 },
3211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3212 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3214 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3217 { .type = NLA_U32 },
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3220
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3225 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3231 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3233 { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3235 { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3237 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3239 { .type = NLA_U8 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 { .type = NLA_U8 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3243 { .type = NLA_U8 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3245 { .type = NLA_U8 },
3246
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3248 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3250 .type = NLA_UNSPEC,
3251 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3253 { .type = NLA_S32 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3255 { .type = NLA_S32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3257 { .type = NLA_U32 },
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3259 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3263 { .type = NLA_BINARY,
3264 .len = IEEE80211_MAX_SSID_LEN + 1 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3268 { .type = NLA_U32 },
3269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3270 { .type = NLA_U8 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3272 { .type = NLA_S32 },
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3274 { .type = NLA_S32 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3276 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277};
3278
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303279/**
3280 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3281 * @ctx: hdd global context
3282 * @data: capabilities data
3283 *
3284 * Return: none
3285 */
3286static void
3287wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291 tSirEXTScanCapabilitiesEvent *data =
3292 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303294 ENTER();
3295
3296 if (wlan_hdd_validate_context(pHddCtx))
3297 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 return;
3299 }
3300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 if (!pMsg)
3302 {
3303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3304 return;
3305 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303307 vos_spin_lock_acquire(&hdd_context_lock);
3308
3309 context = &pHddCtx->ext_scan_context;
3310 /* validate response received from target*/
3311 if (context->request_id != data->requestId)
3312 {
3313 vos_spin_lock_release(&hdd_context_lock);
3314 hddLog(LOGE,
3315 FL("Target response id did not match: request_id %d resposne_id %d"),
3316 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 return;
3318 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 else
3320 {
3321 context->capability_response = *data;
3322 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 }
3324
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303325 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328}
3329
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303330/*
3331 * define short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#define PARAM_REQUEST_ID \
3335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3336#define PARAM_STATUS \
3337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3338#define MAX_SCAN_CACHE_SIZE \
3339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3340#define MAX_SCAN_BUCKETS \
3341 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3342#define MAX_AP_CACHE_PER_SCAN \
3343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3344#define MAX_RSSI_SAMPLE_SIZE \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3346#define MAX_SCAN_RPT_THRHOLD \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3348#define MAX_HOTLIST_BSSIDS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3350#define MAX_BSSID_HISTORY_ENTRIES \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3352#define MAX_HOTLIST_SSIDS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303356
3357static int wlan_hdd_send_ext_scan_capability(void *ctx)
3358{
3359 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3360 struct sk_buff *skb = NULL;
3361 int ret;
3362 tSirEXTScanCapabilitiesEvent *data;
3363 tANI_U32 nl_buf_len;
3364
3365 ret = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != ret)
3367 {
3368 return ret;
3369 }
3370
3371 data = &(pHddCtx->ext_scan_context.capability_response);
3372
3373 nl_buf_len = NLMSG_HDRLEN;
3374 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3375 (sizeof(data->status) + NLA_HDRLEN) +
3376 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3377 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3378 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3379 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3380 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3381 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3382 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3383 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3384
3385 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3386
3387 if (!skb)
3388 {
3389 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3390 return -ENOMEM;
3391 }
3392
3393 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3394 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3395 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3396 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3397 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3398 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3399 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3400 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3401
3402 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3403 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3404 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3405 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3406 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3407 data->maxApPerScan) ||
3408 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3409 data->maxRssiSampleSize) ||
3410 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3411 data->maxScanReportingThreshold) ||
3412 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3413 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3414 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303415 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3416 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303417 {
3418 hddLog(LOGE, FL("nla put fail"));
3419 goto nla_put_failure;
3420 }
3421
3422 cfg80211_vendor_cmd_reply(skb);
3423 return 0;
3424
3425nla_put_failure:
3426 kfree_skb(skb);
3427 return -EINVAL;;
3428}
3429
3430/*
3431 * done with short names for the global vendor params
3432 * used by wlan_hdd_send_ext_scan_capability()
3433 */
3434#undef PARAM_REQUEST_ID
3435#undef PARAM_STATUS
3436#undef MAX_SCAN_CACHE_SIZE
3437#undef MAX_SCAN_BUCKETS
3438#undef MAX_AP_CACHE_PER_SCAN
3439#undef MAX_RSSI_SAMPLE_SIZE
3440#undef MAX_SCAN_RPT_THRHOLD
3441#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303442#undef MAX_BSSID_HISTORY_ENTRIES
3443#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444
3445static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3446{
3447 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3448 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303450 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303452 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303454 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303457 if (!pMsg)
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return;
3461 }
3462
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3464 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 context = &pHddCtx->ext_scan_context;
3467 spin_lock(&hdd_context_lock);
3468 if (context->request_id == pData->requestId) {
3469 context->response_status = pData->status ? -EINVAL : 0;
3470 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303472 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473
3474 /*
3475 * Store the Request ID for comparing with the requestID obtained
3476 * in other requests.HDD shall return a failure is the extscan_stop
3477 * request is issued with a different requestId as that of the
3478 * extscan_start request. Also, This requestId shall be used while
3479 * indicating the full scan results to the upper layers.
3480 * The requestId is stored with the assumption that the firmware
3481 * shall return the ext scan start request's requestId in ext scan
3482 * start response.
3483 */
3484 if (pData->status == 0)
3485 pMac->sme.extScanStartReqId = pData->requestId;
3486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489}
3490
3491
3492static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3493{
3494 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3495 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303496 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303498 ENTER();
3499
3500 if (wlan_hdd_validate_context(pHddCtx)){
3501 return;
3502 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303504 if (!pMsg)
3505 {
3506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 return;
3508 }
3509
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303510 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3511 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513 context = &pHddCtx->ext_scan_context;
3514 spin_lock(&hdd_context_lock);
3515 if (context->request_id == pData->requestId) {
3516 context->response_status = pData->status ? -EINVAL : 0;
3517 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303521 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523}
3524
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3526 void *pMsg)
3527{
3528 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 tpSirEXTScanSetBssidHotListRspParams pData =
3530 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303531 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 ENTER();
3534
3535 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 return;
3537 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 if (!pMsg)
3540 {
3541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3542 return;
3543 }
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3546 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548 context = &pHddCtx->ext_scan_context;
3549 spin_lock(&hdd_context_lock);
3550 if (context->request_id == pData->requestId) {
3551 context->response_status = pData->status ? -EINVAL : 0;
3552 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303556 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558}
3559
3560static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3561 void *pMsg)
3562{
3563 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 tpSirEXTScanResetBssidHotlistRspParams pData =
3565 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303566 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 ENTER();
3569
3570 if (wlan_hdd_validate_context(pHddCtx)) {
3571 return;
3572 }
3573 if (!pMsg)
3574 {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 return;
3577 }
3578
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3580 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303582 context = &pHddCtx->ext_scan_context;
3583 spin_lock(&hdd_context_lock);
3584 if (context->request_id == pData->requestId) {
3585 context->response_status = pData->status ? -EINVAL : 0;
3586 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592}
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3595 void *pMsg)
3596{
3597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 tANI_S32 totalResults;
3601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3603 struct hdd_ext_scan_context *context;
3604 bool ignore_cached_results = false;
3605 tExtscanCachedScanResult *result;
3606 struct nlattr *nla_results;
3607 tANI_U16 ieLength= 0;
3608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303610 ENTER();
3611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303615 if (!pMsg)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3618 return;
3619 }
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 spin_lock(&hdd_context_lock);
3622 context = &pHddCtx->ext_scan_context;
3623 ignore_cached_results = context->ignore_cached_results;
3624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 if (ignore_cached_results) {
3627 hddLog(LOGE,
3628 FL("Ignore the cached results received after timeout"));
3629 return;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3638 scan_id_index++) {
3639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 totalResults = result->num_results;
3642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3643 result->scan_id, result->flags, totalResults);
3644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 do{
3647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3653
3654 if (!skb) {
3655 hddLog(VOS_TRACE_LEVEL_ERROR,
3656 FL("cfg80211_vendor_event_alloc failed"));
3657 return;
3658 }
3659
3660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3661
3662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3663 pData->requestId) ||
3664 nla_put_u32(skb,
3665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3666 resultsPerEvent)) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put_u8(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 if (nla_put_u32(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3680 result->scan_id)) {
3681 hddLog(LOGE, FL("put fail"));
3682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303685 nla_results = nla_nest_start(skb,
3686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3687 if (!nla_results)
3688 goto fail;
3689
3690 if (resultsPerEvent) {
3691 struct nlattr *aps;
3692 struct nlattr *nla_result;
3693
3694 nla_result = nla_nest_start(skb, scan_id_index);
3695 if(!nla_result)
3696 goto fail;
3697
3698 if (nla_put_u32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3700 result->scan_id) ||
3701 nla_put_u32(skb,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3703 result->flags) ||
3704 nla_put_u32(skb,
3705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3706 totalResults)) {
3707 hddLog(LOGE, FL("put fail"));
3708 goto fail;
3709 }
3710
3711 aps = nla_nest_start(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3713 if (!aps)
3714 {
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3716 goto fail;
3717 }
3718
3719 head_ptr = (tpSirWifiScanResult) &(result->ap);
3720
3721 for (j = 0; j < resultsPerEvent; j++, i++) {
3722 struct nlattr *ap;
3723 pSirWifiScanResult = head_ptr + i;
3724
3725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303726 * Firmware returns timestamp from extscan_start till
3727 * BSSID was cached (in micro seconds). Add this with
3728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303729 * to derive the time since boot when the
3730 * BSSID was cached.
3731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303732 pSirWifiScanResult->ts +=
3733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3735 "Ssid (%s)"
3736 "Bssid: %pM "
3737 "Channel (%u)"
3738 "Rssi (%d)"
3739 "RTT (%u)"
3740 "RTT_SD (%u)"
3741 "Beacon Period %u"
3742 "Capability 0x%x "
3743 "Ie length %d",
3744 i,
3745 pSirWifiScanResult->ts,
3746 pSirWifiScanResult->ssid,
3747 pSirWifiScanResult->bssid,
3748 pSirWifiScanResult->channel,
3749 pSirWifiScanResult->rssi,
3750 pSirWifiScanResult->rtt,
3751 pSirWifiScanResult->rtt_sd,
3752 pSirWifiScanResult->beaconPeriod,
3753 pSirWifiScanResult->capability,
3754 ieLength);
3755
3756 ap = nla_nest_start(skb, j + 1);
3757 if (!ap)
3758 {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3760 goto fail;
3761 }
3762
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303763 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3765 pSirWifiScanResult->ts) )
3766 {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3768 goto fail;
3769 }
3770 if (nla_put(skb,
3771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3772 sizeof(pSirWifiScanResult->ssid),
3773 pSirWifiScanResult->ssid) )
3774 {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3776 goto fail;
3777 }
3778 if (nla_put(skb,
3779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3780 sizeof(pSirWifiScanResult->bssid),
3781 pSirWifiScanResult->bssid) )
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3784 goto fail;
3785 }
3786 if (nla_put_u32(skb,
3787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3788 pSirWifiScanResult->channel) )
3789 {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3791 goto fail;
3792 }
3793 if (nla_put_s32(skb,
3794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3795 pSirWifiScanResult->rssi) )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3798 goto fail;
3799 }
3800 if (nla_put_u32(skb,
3801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3802 pSirWifiScanResult->rtt) )
3803 {
3804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3805 goto fail;
3806 }
3807 if (nla_put_u32(skb,
3808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3809 pSirWifiScanResult->rtt_sd))
3810 {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3812 goto fail;
3813 }
3814 if (nla_put_u32(skb,
3815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3816 pSirWifiScanResult->beaconPeriod))
3817 {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3819 goto fail;
3820 }
3821 if (nla_put_u32(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3823 pSirWifiScanResult->capability))
3824 {
3825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3826 goto fail;
3827 }
3828 if (nla_put_u32(skb,
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3830 ieLength))
3831 {
3832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3833 goto fail;
3834 }
3835
3836 if (ieLength)
3837 if (nla_put(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3839 ieLength, ie)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3841 goto fail;
3842 }
3843
3844 nla_nest_end(skb, ap);
3845 }
3846 nla_nest_end(skb, aps);
3847 nla_nest_end(skb, nla_result);
3848 }
3849
3850 nla_nest_end(skb, nla_results);
3851
3852 cfg80211_vendor_cmd_reply(skb);
3853
3854 } while (totalResults > 0);
3855 }
3856
3857 if (!pData->moreData) {
3858 spin_lock(&hdd_context_lock);
3859 context->response_status = 0;
3860 complete(&context->response_event);
3861 spin_unlock(&hdd_context_lock);
3862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865 return;
3866fail:
3867 kfree_skb(skb);
3868 return;
3869}
3870
3871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3872 void *pMsg)
3873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 ENTER();
3880
3881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303882 hddLog(LOGE,
3883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303884 return;
3885 }
3886 if (!pMsg)
3887 {
3888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 return;
3890 }
3891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 if (pData->bss_found)
3893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3894 else
3895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3899 NULL,
3900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303903
3904 if (!skb) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR,
3906 FL("cfg80211_vendor_event_alloc failed"));
3907 return;
3908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3914
3915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3917 "Ssid (%s) "
3918 "Bssid (" MAC_ADDRESS_STR ") "
3919 "Channel (%u) "
3920 "Rssi (%d) "
3921 "RTT (%u) "
3922 "RTT_SD (%u) ",
3923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303924 pData->bssHotlist[i].ts,
3925 pData->bssHotlist[i].ssid,
3926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3927 pData->bssHotlist[i].channel,
3928 pData->bssHotlist[i].rssi,
3929 pData->bssHotlist[i].rtt,
3930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 }
3932
3933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3934 pData->requestId) ||
3935 nla_put_u32(skb,
3936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3939 goto fail;
3940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 struct nlattr *aps;
3943
3944 aps = nla_nest_start(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3946 if (!aps)
3947 goto fail;
3948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 struct nlattr *ap;
3951
3952 ap = nla_nest_start(skb, i + 1);
3953 if (!ap)
3954 goto fail;
3955
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303956 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 nla_put(skb,
3960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 sizeof(pData->bssHotlist[i].ssid),
3962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303963 nla_put(skb,
3964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303965 sizeof(pData->bssHotlist[i].bssid),
3966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 nla_put_u32(skb,
3968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 nla_put_s32(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put_u32(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 goto fail;
3980
3981 nla_nest_end(skb, ap);
3982 }
3983 nla_nest_end(skb, aps);
3984
3985 if (nla_put_u8(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3987 pData->moreData))
3988 goto fail;
3989 }
3990
3991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 return;
3994
3995fail:
3996 kfree_skb(skb);
3997 return;
3998
3999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000
4001static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4002 void *pMsg)
4003{
4004 struct sk_buff *skb;
4005 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4006 tpSirWifiFullScanResultEvent pData =
4007 (tpSirWifiFullScanResultEvent) (pMsg);
4008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 ENTER();
4010
4011 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304012 hddLog(LOGE,
4013 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 return;
4015 }
4016 if (!pMsg)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020 }
4021
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 /*
4023 * If the full scan result including IE data exceeds NL 4K size
4024 * limitation, drop that beacon/probe rsp frame.
4025 */
4026 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4027 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4028 return;
4029 }
4030
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4033 NULL,
4034#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4036 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4037 GFP_KERNEL);
4038
4039 if (!skb) {
4040 hddLog(VOS_TRACE_LEVEL_ERROR,
4041 FL("cfg80211_vendor_event_alloc failed"));
4042 return;
4043 }
4044
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4046 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4047 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4048 "Ssid (%s)"
4049 "Bssid (" MAC_ADDRESS_STR ")"
4050 "Channel (%u)"
4051 "Rssi (%d)"
4052 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304053 "RTT_SD (%u)"
4054 "Bcn Period %d"
4055 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pData->ap.ts,
4057 pData->ap.ssid,
4058 MAC_ADDR_ARRAY(pData->ap.bssid),
4059 pData->ap.channel,
4060 pData->ap.rssi,
4061 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 pData->ap.rtt_sd,
4063 pData->ap.beaconPeriod,
4064 pData->ap.capability);
4065
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4068 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304069 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4071 pData->ap.ts) ||
4072 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4073 sizeof(pData->ap.ssid),
4074 pData->ap.ssid) ||
4075 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4076 WNI_CFG_BSSID_LEN,
4077 pData->ap.bssid) ||
4078 nla_put_u32(skb,
4079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4080 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304081 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 pData->ap.rssi) ||
4083 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4084 pData->ap.rtt) ||
4085 nla_put_u32(skb,
4086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4087 pData->ap.rtt_sd) ||
4088 nla_put_u16(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4090 pData->ap.beaconPeriod) ||
4091 nla_put_u16(skb,
4092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4093 pData->ap.capability) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304096 pData->ieLength) ||
4097 nla_put_u8(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4099 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4102 goto nla_put_failure;
4103 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304104
4105 if (pData->ieLength) {
4106 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4107 pData->ieLength,
4108 pData->ie))
4109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113 }
4114
4115 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304116 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 return;
4118
4119nla_put_failure:
4120 kfree_skb(skb);
4121 return;
4122}
4123
4124static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4125 void *pMsg)
4126{
4127 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4128 struct sk_buff *skb = NULL;
4129 tpSirEXTScanResultsAvailableIndParams pData =
4130 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4131
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 ENTER();
4133
4134 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304135 hddLog(LOGE,
4136 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304137 return;
4138 }
4139 if (!pMsg)
4140 {
4141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 return;
4143 }
4144
4145 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4147 NULL,
4148#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4150 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4151 GFP_KERNEL);
4152
4153 if (!skb) {
4154 hddLog(VOS_TRACE_LEVEL_ERROR,
4155 FL("cfg80211_vendor_event_alloc failed"));
4156 return;
4157 }
4158
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4160 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4161 pData->numResultsAvailable);
4162 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4163 pData->requestId) ||
4164 nla_put_u32(skb,
4165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4166 pData->numResultsAvailable)) {
4167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4168 goto nla_put_failure;
4169 }
4170
4171 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304172 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173 return;
4174
4175nla_put_failure:
4176 kfree_skb(skb);
4177 return;
4178}
4179
4180static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4181{
4182 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4183 struct sk_buff *skb = NULL;
4184 tpSirEXTScanProgressIndParams pData =
4185 (tpSirEXTScanProgressIndParams) pMsg;
4186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304187 ENTER();
4188
4189 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304190 hddLog(LOGE,
4191 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304192 return;
4193 }
4194 if (!pMsg)
4195 {
4196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 return;
4198 }
4199
4200 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4202 NULL,
4203#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4205 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4206 GFP_KERNEL);
4207
4208 if (!skb) {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,
4210 FL("cfg80211_vendor_event_alloc failed"));
4211 return;
4212 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4215 pData->extScanEventType);
4216 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4217 pData->status);
4218
4219 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4220 pData->extScanEventType) ||
4221 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4223 pData->requestId) ||
4224 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4226 pData->status)) {
4227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4228 goto nla_put_failure;
4229 }
4230
4231 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304232 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 return;
4234
4235nla_put_failure:
4236 kfree_skb(skb);
4237 return;
4238}
4239
4240void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4241 void *pMsg)
4242{
4243 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 return;
4249 }
4250
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4252
4253
4254 switch(evType) {
4255 case SIR_HAL_EXTSCAN_START_RSP:
4256 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4257 break;
4258
4259 case SIR_HAL_EXTSCAN_STOP_RSP:
4260 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4261 break;
4262 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4263 /* There is no need to send this response to upper layer
4264 Just log the message */
4265 hddLog(VOS_TRACE_LEVEL_INFO,
4266 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4267 break;
4268 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4269 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4270 break;
4271
4272 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4273 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4274 break;
4275
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304277 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 break;
4279 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4280 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4281 break;
4282 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4283 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4284 break;
4285 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4286 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4287 break;
4288 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4289 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4290 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4292 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4293 break;
4294 default:
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4296 break;
4297 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299}
4300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304301static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4302 struct wireless_dev *wdev,
4303 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304{
Dino Myclee8843b32014-07-04 14:21:45 +05304305 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304306 struct net_device *dev = wdev->netdev;
4307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4309 struct nlattr
4310 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4311 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304312 struct hdd_ext_scan_context *context;
4313 unsigned long rc;
4314 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ENTER();
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339
4340 /* Parse and fetch request Id */
4341 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4343 return -EINVAL;
4344 }
4345
Dino Myclee8843b32014-07-04 14:21:45 +05304346 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304353 vos_spin_lock_acquire(&hdd_context_lock);
4354 context = &pHddCtx->ext_scan_context;
4355 context->request_id = reqMsg.requestId;
4356 INIT_COMPLETION(context->response_event);
4357 vos_spin_lock_release(&hdd_context_lock);
4358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 if (!HAL_STATUS_SUCCESS(status)) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR,
4362 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363 return -EINVAL;
4364 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304365
4366 rc = wait_for_completion_timeout(&context->response_event,
4367 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4368 if (!rc) {
4369 hddLog(LOGE, FL("Target response timed out"));
4370 return -ETIMEDOUT;
4371 }
4372
4373 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4374 if (ret)
4375 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4376
4377 return ret;
4378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304380 return 0;
4381}
4382
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304383static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4384 struct wireless_dev *wdev,
4385 const void *data, int dataLen)
4386{
4387 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304389 vos_ssr_protect(__func__);
4390 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4391 vos_ssr_unprotect(__func__);
4392
4393 return ret;
4394}
4395
4396static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
4398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr
4405 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4406 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304407 struct hdd_ext_scan_context *context;
4408 unsigned long rc;
4409 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304411 ENTER();
4412
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304413 if (VOS_FTM_MODE == hdd_get_conparam()) {
4414 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4415 return -EINVAL;
4416 }
4417
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 status = wlan_hdd_validate_context(pHddCtx);
4419 if (0 != status)
4420 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421 return -EINVAL;
4422 }
Dino Myclee8843b32014-07-04 14:21:45 +05304423 /* check the EXTScan Capability */
4424 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304425 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4426 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304427 {
4428 hddLog(VOS_TRACE_LEVEL_ERROR,
4429 FL("EXTScan not enabled/supported by Firmware"));
4430 return -EINVAL;
4431 }
4432
Dino Mycle6fb96c12014-06-10 11:52:40 +05304433 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4434 data, dataLen,
4435 wlan_hdd_extscan_config_policy)) {
4436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4437 return -EINVAL;
4438 }
4439 /* Parse and fetch request Id */
4440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4442 return -EINVAL;
4443 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444
Dino Myclee8843b32014-07-04 14:21:45 +05304445 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4447
Dino Myclee8843b32014-07-04 14:21:45 +05304448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449
Dino Myclee8843b32014-07-04 14:21:45 +05304450 reqMsg.sessionId = pAdapter->sessionId;
4451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
4453 /* Parse and fetch flush parameter */
4454 if (!tb
4455 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4456 {
4457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4458 goto failed;
4459 }
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4462
Dino Myclee8843b32014-07-04 14:21:45 +05304463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304465 spin_lock(&hdd_context_lock);
4466 context = &pHddCtx->ext_scan_context;
4467 context->request_id = reqMsg.requestId;
4468 context->ignore_cached_results = false;
4469 INIT_COMPLETION(context->response_event);
4470 spin_unlock(&hdd_context_lock);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473 if (!HAL_STATUS_SUCCESS(status)) {
4474 hddLog(VOS_TRACE_LEVEL_ERROR,
4475 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304476 return -EINVAL;
4477 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304478
4479 rc = wait_for_completion_timeout(&context->response_event,
4480 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4481 if (!rc) {
4482 hddLog(LOGE, FL("Target response timed out"));
4483 retval = -ETIMEDOUT;
4484 spin_lock(&hdd_context_lock);
4485 context->ignore_cached_results = true;
4486 spin_unlock(&hdd_context_lock);
4487 } else {
4488 spin_lock(&hdd_context_lock);
4489 retval = context->response_status;
4490 spin_unlock(&hdd_context_lock);
4491 }
4492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304493 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304494 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495
4496failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497 return -EINVAL;
4498}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304499static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4500 struct wireless_dev *wdev,
4501 const void *data, int dataLen)
4502{
4503 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304505 vos_ssr_protect(__func__);
4506 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4507 vos_ssr_unprotect(__func__);
4508
4509 return ret;
4510}
4511
4512static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304514 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304515{
4516 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4517 struct net_device *dev = wdev->netdev;
4518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4520 struct nlattr
4521 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4522 struct nlattr
4523 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4524 struct nlattr *apTh;
4525 eHalStatus status;
4526 tANI_U8 i = 0;
4527 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304528 struct hdd_ext_scan_context *context;
4529 tANI_U32 request_id;
4530 unsigned long rc;
4531 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304535 if (VOS_FTM_MODE == hdd_get_conparam()) {
4536 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4537 return -EINVAL;
4538 }
4539
Dino Mycle6fb96c12014-06-10 11:52:40 +05304540 status = wlan_hdd_validate_context(pHddCtx);
4541 if (0 != status)
4542 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304543 return -EINVAL;
4544 }
Dino Myclee8843b32014-07-04 14:21:45 +05304545 /* check the EXTScan Capability */
4546 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304547 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4548 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304549 {
4550 hddLog(VOS_TRACE_LEVEL_ERROR,
4551 FL("EXTScan not enabled/supported by Firmware"));
4552 return -EINVAL;
4553 }
4554
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4556 data, dataLen,
4557 wlan_hdd_extscan_config_policy)) {
4558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4559 return -EINVAL;
4560 }
4561
4562 /* Parse and fetch request Id */
4563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4565 return -EINVAL;
4566 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4568 vos_mem_malloc(sizeof(*pReqMsg));
4569 if (!pReqMsg) {
4570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4571 return -ENOMEM;
4572 }
4573
Dino Myclee8843b32014-07-04 14:21:45 +05304574
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 pReqMsg->requestId = nla_get_u32(
4576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4578
4579 /* Parse and fetch number of APs */
4580 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4582 goto fail;
4583 }
4584
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304585 /* Parse and fetch lost ap sample size */
4586 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4587 hddLog(LOGE, FL("attr lost ap sample size failed"));
4588 goto fail;
4589 }
4590
4591 pReqMsg->lostBssidSampleSize = nla_get_u32(
4592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4593 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 pReqMsg->sessionId = pAdapter->sessionId;
4596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4597
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304598 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304600 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4601 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4602 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4603 goto fail;
4604 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
4607 nla_for_each_nested(apTh,
4608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (i == pReqMsg->numBssid) {
4610 hddLog(LOGW, FL("Ignoring excess AP"));
4611 break;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4615 nla_data(apTh), nla_len(apTh),
4616 NULL)) {
4617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4618 goto fail;
4619 }
4620
4621 /* Parse and fetch MAC address */
4622 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4624 goto fail;
4625 }
4626 memcpy(pReqMsg->ap[i].bssid, nla_data(
4627 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4628 sizeof(tSirMacAddr));
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4630
4631 /* Parse and fetch low RSSI */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4634 goto fail;
4635 }
4636 pReqMsg->ap[i].low = nla_get_s32(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4639
4640 /* Parse and fetch high RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].high = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4648 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 i++;
4650 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304651
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304652 if (i < pReqMsg->numBssid) {
4653 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4654 i, pReqMsg->numBssid);
4655 pReqMsg->numBssid = i;
4656 }
4657
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304658 context = &pHddCtx->ext_scan_context;
4659 spin_lock(&hdd_context_lock);
4660 INIT_COMPLETION(context->response_event);
4661 context->request_id = request_id = pReqMsg->requestId;
4662 spin_unlock(&hdd_context_lock);
4663
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4665 if (!HAL_STATUS_SUCCESS(status)) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR,
4667 FL("sme_SetBssHotlist failed(err=%d)"), status);
4668 vos_mem_free(pReqMsg);
4669 return -EINVAL;
4670 }
4671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304672 /* request was sent -- wait for the response */
4673 rc = wait_for_completion_timeout(&context->response_event,
4674 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4675
4676 if (!rc) {
4677 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4678 retval = -ETIMEDOUT;
4679 } else {
4680 spin_lock(&hdd_context_lock);
4681 if (context->request_id == request_id)
4682 retval = context->response_status;
4683 else
4684 retval = -EINVAL;
4685 spin_unlock(&hdd_context_lock);
4686 }
4687
Dino Myclee8843b32014-07-04 14:21:45 +05304688 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304689 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304690 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304691
4692fail:
4693 vos_mem_free(pReqMsg);
4694 return -EINVAL;
4695}
4696
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304697static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4698 struct wireless_dev *wdev,
4699 const void *data, int dataLen)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4705 dataLen);
4706 vos_ssr_unprotect(__func__);
4707
4708 return ret;
4709}
4710
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304711static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304713 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4716 struct net_device *dev = wdev->netdev;
4717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4718 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4719 uint8_t num_channels = 0;
4720 uint8_t num_chan_new = 0;
4721 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304723 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 tWifiBand wifiBand;
4725 eHalStatus status;
4726 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304727 tANI_U8 i,j,k;
4728 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ENTER();
4731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = wlan_hdd_validate_context(pHddCtx);
4733 if (0 != status)
4734 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
4736 }
Dino Myclee8843b32014-07-04 14:21:45 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4739 data, dataLen,
4740 wlan_hdd_extscan_config_policy)) {
4741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4742 return -EINVAL;
4743 }
4744
4745 /* Parse and fetch request Id */
4746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4748 return -EINVAL;
4749 }
4750 requestId = nla_get_u32(
4751 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4753
4754 /* Parse and fetch wifi band */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4756 {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4758 return -EINVAL;
4759 }
4760 wifiBand = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4763
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304764 /* Parse and fetch max channels */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4766 {
4767 hddLog(LOGE, FL("attr max channels failed"));
4768 return -EINVAL;
4769 }
4770 maxChannels = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304775 wifiBand, chan_list,
4776 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777 if (eHAL_STATUS_SUCCESS != status) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR,
4779 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4780 return -EINVAL;
4781 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304782
Agrawal Ashish16abf782016-08-18 22:42:59 +05304783 num_channels = VOS_MIN(num_channels, maxChannels);
4784 num_chan_new = num_channels;
4785 /* remove the indoor only channels if iface is SAP */
4786 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4787 {
4788 num_chan_new = 0;
4789 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304790 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304791 if (wiphy->bands[j] == NULL)
4792 continue;
4793 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4794 if ((chan_list[i] ==
4795 wiphy->bands[j]->channels[k].center_freq) &&
4796 (!(wiphy->bands[j]->channels[k].flags &
4797 IEEE80211_CHAN_INDOOR_ONLY))) {
4798 chan_list[num_chan_new] = chan_list[i];
4799 num_chan_new++;
4800 }
4801 }
4802 }
4803 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304804
Agrawal Ashish16abf782016-08-18 22:42:59 +05304805 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4806 for (i = 0; i < num_chan_new; i++)
4807 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4808 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809
4810 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304811 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 NLMSG_HDRLEN);
4813
4814 if (!replySkb) {
4815 hddLog(VOS_TRACE_LEVEL_ERROR,
4816 FL("valid channels: buffer alloc fail"));
4817 return -EINVAL;
4818 }
4819 if (nla_put_u32(replySkb,
4820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304823 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
4825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4826 kfree_skb(replySkb);
4827 return -EINVAL;
4828 }
4829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304830 ret = cfg80211_vendor_cmd_reply(replySkb);
4831
4832 EXIT();
4833 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834}
4835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304836static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4837 struct wireless_dev *wdev,
4838 const void *data, int dataLen)
4839{
4840 int ret = 0;
4841
4842 vos_ssr_protect(__func__);
4843 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4844 dataLen);
4845 vos_ssr_unprotect(__func__);
4846
4847 return ret;
4848}
4849
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304850static int hdd_extscan_start_fill_bucket_channel_spec(
4851 hdd_context_t *pHddCtx,
4852 tpSirEXTScanStartReqParams pReqMsg,
4853 struct nlattr **tb)
4854{
4855 struct nlattr *bucket[
4856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4857 struct nlattr *channel[
4858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4859 struct nlattr *buckets;
4860 struct nlattr *channels;
4861 int rem1, rem2;
4862 eHalStatus status;
4863 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304864 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304865 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4866 tANI_U32 passive_max_chn_time, active_max_chn_time;
4867
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304868 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304869 bktIndex = 0;
4870
4871 nla_for_each_nested(buckets,
4872 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 if (bktIndex >= expected_buckets) {
4874 hddLog(LOGW, FL("ignoring excess buckets"));
4875 break;
4876 }
4877
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304879 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 nla_data(buckets), nla_len(buckets),
4881 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304882 hddLog(LOGE, FL("nla_parse failed"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch bucket spec */
4887 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4888 hddLog(LOGE, FL("attr bucket index failed"));
4889 return -EINVAL;
4890 }
4891 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4892 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4893 hddLog(LOG1, FL("Bucket spec Index %d"),
4894 pReqMsg->buckets[bktIndex].bucket);
4895
4896 /* Parse and fetch wifi band */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4898 hddLog(LOGE, FL("attr wifi band failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4903 hddLog(LOG1, FL("Wifi band %d"),
4904 pReqMsg->buckets[bktIndex].band);
4905
4906 /* Parse and fetch period */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4908 hddLog(LOGE, FL("attr period failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4913 hddLog(LOG1, FL("period %d"),
4914 pReqMsg->buckets[bktIndex].period);
4915
4916 /* Parse and fetch report events */
4917 if (!bucket[
4918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4919 hddLog(LOGE, FL("attr report events failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4923 bucket[
4924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4925 hddLog(LOG1, FL("report events %d"),
4926 pReqMsg->buckets[bktIndex].reportEvents);
4927
4928 /* Parse and fetch max period */
4929 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4930 hddLog(LOGE, FL("attr max period failed"));
4931 return -EINVAL;
4932 }
4933 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4935 hddLog(LOG1, FL("max period %u"),
4936 pReqMsg->buckets[bktIndex].max_period);
4937
4938 /* Parse and fetch exponent */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4940 hddLog(LOGE, FL("attr exponent failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4945 hddLog(LOG1, FL("exponent %u"),
4946 pReqMsg->buckets[bktIndex].exponent);
4947
4948 /* Parse and fetch step count */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4950 hddLog(LOGE, FL("attr step count failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4955 hddLog(LOG1, FL("Step count %u"),
4956 pReqMsg->buckets[bktIndex].step_count);
4957
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4959 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4960
4961 /* Framework shall pass the channel list if the input WiFi band is
4962 * WIFI_BAND_UNSPECIFIED.
4963 * If the input WiFi band is specified (any value other than
4964 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4965 */
4966 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4967 numChannels = 0;
4968 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4969 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4970 pReqMsg->buckets[bktIndex].band,
4971 chanList, &numChannels);
4972 if (!HAL_STATUS_SUCCESS(status)) {
4973 hddLog(LOGE,
4974 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4975 status);
4976 return -EINVAL;
4977 }
4978
4979 pReqMsg->buckets[bktIndex].numChannels =
4980 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4981 hddLog(LOG1, FL("Num channels %d"),
4982 pReqMsg->buckets[bktIndex].numChannels);
4983
4984 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4985 j++) {
4986 pReqMsg->buckets[bktIndex].channels[j].channel =
4987 chanList[j];
4988 pReqMsg->buckets[bktIndex].channels[j].
4989 chnlClass = 0;
4990 if (CSR_IS_CHANNEL_DFS(
4991 vos_freq_to_chan(chanList[j]))) {
4992 pReqMsg->buckets[bktIndex].channels[j].
4993 passive = 1;
4994 pReqMsg->buckets[bktIndex].channels[j].
4995 dwellTimeMs = passive_max_chn_time;
4996 } else {
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 passive = 0;
4999 pReqMsg->buckets[bktIndex].channels[j].
5000 dwellTimeMs = active_max_chn_time;
5001 }
5002
5003 hddLog(LOG1,
5004 "Channel %u Passive %u Dwell time %u ms",
5005 pReqMsg->buckets[bktIndex].channels[j].channel,
5006 pReqMsg->buckets[bktIndex].channels[j].passive,
5007 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5008 }
5009
5010 bktIndex++;
5011 continue;
5012 }
5013
5014 /* Parse and fetch number of channels */
5015 if (!bucket[
5016 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5017 hddLog(LOGE, FL("attr num channels failed"));
5018 return -EINVAL;
5019 }
5020
5021 pReqMsg->buckets[bktIndex].numChannels =
5022 nla_get_u32(bucket[
5023 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5024 hddLog(LOG1, FL("num channels %d"),
5025 pReqMsg->buckets[bktIndex].numChannels);
5026
5027 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5028 hddLog(LOGE, FL("attr channel spec failed"));
5029 return -EINVAL;
5030 }
5031
5032 j = 0;
5033 nla_for_each_nested(channels,
5034 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5035 if (nla_parse(channel,
5036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5037 nla_data(channels), nla_len(channels),
5038 wlan_hdd_extscan_config_policy)) {
5039 hddLog(LOGE, FL("nla_parse failed"));
5040 return -EINVAL;
5041 }
5042
5043 /* Parse and fetch channel */
5044 if (!channel[
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5046 hddLog(LOGE, FL("attr channel failed"));
5047 return -EINVAL;
5048 }
5049 pReqMsg->buckets[bktIndex].channels[j].channel =
5050 nla_get_u32(channel[
5051 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5052 hddLog(LOG1, FL("channel %u"),
5053 pReqMsg->buckets[bktIndex].channels[j].channel);
5054
5055 /* Parse and fetch dwell time */
5056 if (!channel[
5057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5058 hddLog(LOGE, FL("attr dwelltime failed"));
5059 return -EINVAL;
5060 }
5061 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5062 nla_get_u32(channel[
5063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5064
5065 hddLog(LOG1, FL("Dwell time (%u ms)"),
5066 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5067
5068
5069 /* Parse and fetch channel spec passive */
5070 if (!channel[
5071 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5072 hddLog(LOGE,
5073 FL("attr channel spec passive failed"));
5074 return -EINVAL;
5075 }
5076 pReqMsg->buckets[bktIndex].channels[j].passive =
5077 nla_get_u8(channel[
5078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5079 hddLog(LOG1, FL("Chnl spec passive %u"),
5080 pReqMsg->buckets[bktIndex].channels[j].passive);
5081
5082 j++;
5083 }
5084
5085 bktIndex++;
5086 }
5087
5088 return 0;
5089}
5090
5091
5092/*
5093 * define short names for the global vendor params
5094 * used by wlan_hdd_cfg80211_extscan_start()
5095 */
5096#define PARAM_MAX \
5097QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5098#define PARAM_REQUEST_ID \
5099QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5100#define PARAM_BASE_PERIOD \
5101QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5102#define PARAM_MAX_AP_PER_SCAN \
5103QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5104#define PARAM_RPT_THRHLD_PERCENT \
5105QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5106#define PARAM_RPT_THRHLD_NUM_SCANS \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5108#define PARAM_NUM_BUCKETS \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305111static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305112 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305113 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114{
Dino Myclee8843b32014-07-04 14:21:45 +05305115 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 struct net_device *dev = wdev->netdev;
5117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5119 struct nlattr *tb[PARAM_MAX + 1];
5120 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305122 tANI_U32 request_id;
5123 struct hdd_ext_scan_context *context;
5124 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305126 ENTER();
5127
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 if (VOS_FTM_MODE == hdd_get_conparam()) {
5129 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5130 return -EINVAL;
5131 }
5132
Dino Mycle6fb96c12014-06-10 11:52:40 +05305133 status = wlan_hdd_validate_context(pHddCtx);
5134 if (0 != status)
5135 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136 return -EINVAL;
5137 }
Dino Myclee8843b32014-07-04 14:21:45 +05305138 /* check the EXTScan Capability */
5139 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305140 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5141 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305142 {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 FL("EXTScan not enabled/supported by Firmware"));
5145 return -EINVAL;
5146 }
5147
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305148 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305149 data, dataLen,
5150 wlan_hdd_extscan_config_policy)) {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305156 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5158 return -EINVAL;
5159 }
5160
Dino Myclee8843b32014-07-04 14:21:45 +05305161 pReqMsg = (tpSirEXTScanStartReqParams)
5162 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305163 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5165 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 }
5167
5168 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305169 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5171
5172 pReqMsg->sessionId = pAdapter->sessionId;
5173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5174
5175 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305176 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5178 goto fail;
5179 }
5180 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305181 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5183 pReqMsg->basePeriod);
5184
5185 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5188 goto fail;
5189 }
5190 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5193 pReqMsg->maxAPperScan);
5194
5195 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5198 goto fail;
5199 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 pReqMsg->reportThresholdPercent = nla_get_u8(
5201 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 pReqMsg->reportThresholdPercent);
5204
5205 /* Parse and fetch report threshold num scans */
5206 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5207 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5208 goto fail;
5209 }
5210 pReqMsg->reportThresholdNumScans = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5212 hddLog(LOG1, FL("Report Threshold num scans %d"),
5213 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305214
5215 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305216 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5218 goto fail;
5219 }
5220 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305221 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305222 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5223 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5224 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5225 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5226 }
5227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5228 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305229
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5232 goto fail;
5233 }
5234
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305235 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5238 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305239
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 context = &pHddCtx->ext_scan_context;
5241 spin_lock(&hdd_context_lock);
5242 INIT_COMPLETION(context->response_event);
5243 context->request_id = request_id = pReqMsg->requestId;
5244 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305245
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5247 if (!HAL_STATUS_SUCCESS(status)) {
5248 hddLog(VOS_TRACE_LEVEL_ERROR,
5249 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 goto fail;
5251 }
5252
Srinivas Dasari91727c12016-03-23 17:59:06 +05305253 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5254
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 /* request was sent -- wait for the response */
5256 rc = wait_for_completion_timeout(&context->response_event,
5257 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5258
5259 if (!rc) {
5260 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5261 retval = -ETIMEDOUT;
5262 } else {
5263 spin_lock(&hdd_context_lock);
5264 if (context->request_id == request_id)
5265 retval = context->response_status;
5266 else
5267 retval = -EINVAL;
5268 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 }
5270
Dino Myclee8843b32014-07-04 14:21:45 +05305271 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305272 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305273 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305274
5275fail:
5276 vos_mem_free(pReqMsg);
5277 return -EINVAL;
5278}
5279
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305280/*
5281 * done with short names for the global vendor params
5282 * used by wlan_hdd_cfg80211_extscan_start()
5283 */
5284#undef PARAM_MAX
5285#undef PARAM_REQUEST_ID
5286#undef PARAM_BASE_PERIOD
5287#undef PARAMS_MAX_AP_PER_SCAN
5288#undef PARAMS_RPT_THRHLD_PERCENT
5289#undef PARAMS_RPT_THRHLD_NUM_SCANS
5290#undef PARAMS_NUM_BUCKETS
5291
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305292static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5293 struct wireless_dev *wdev,
5294 const void *data, int dataLen)
5295{
5296 int ret = 0;
5297
5298 vos_ssr_protect(__func__);
5299 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5300 vos_ssr_unprotect(__func__);
5301
5302 return ret;
5303}
5304
5305static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305307 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305308{
Dino Myclee8843b32014-07-04 14:21:45 +05305309 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct net_device *dev = wdev->netdev;
5311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5314 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305315 int retval;
5316 unsigned long rc;
5317 struct hdd_ext_scan_context *context;
5318 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305320 ENTER();
5321
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305322 if (VOS_FTM_MODE == hdd_get_conparam()) {
5323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5324 return -EINVAL;
5325 }
5326
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327 status = wlan_hdd_validate_context(pHddCtx);
5328 if (0 != status)
5329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305330 return -EINVAL;
5331 }
Dino Myclee8843b32014-07-04 14:21:45 +05305332 /* check the EXTScan Capability */
5333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305336 {
5337 hddLog(VOS_TRACE_LEVEL_ERROR,
5338 FL("EXTScan not enabled/supported by Firmware"));
5339 return -EINVAL;
5340 }
5341
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5343 data, dataLen,
5344 wlan_hdd_extscan_config_policy)) {
5345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5346 return -EINVAL;
5347 }
5348
5349 /* Parse and fetch request Id */
5350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5352 return -EINVAL;
5353 }
5354
Dino Myclee8843b32014-07-04 14:21:45 +05305355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358
Dino Myclee8843b32014-07-04 14:21:45 +05305359 reqMsg.sessionId = pAdapter->sessionId;
5360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305361
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305362 context = &pHddCtx->ext_scan_context;
5363 spin_lock(&hdd_context_lock);
5364 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305365 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305366 spin_unlock(&hdd_context_lock);
5367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369 if (!HAL_STATUS_SUCCESS(status)) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR,
5371 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372 return -EINVAL;
5373 }
5374
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 /* request was sent -- wait for the response */
5376 rc = wait_for_completion_timeout(&context->response_event,
5377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5378
5379 if (!rc) {
5380 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5381 retval = -ETIMEDOUT;
5382 } else {
5383 spin_lock(&hdd_context_lock);
5384 if (context->request_id == request_id)
5385 retval = context->response_status;
5386 else
5387 retval = -EINVAL;
5388 spin_unlock(&hdd_context_lock);
5389 }
5390
5391 return retval;
5392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305393 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394 return 0;
5395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data, int dataLen)
5400{
5401 int ret = 0;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
5410static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305412 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305413{
Dino Myclee8843b32014-07-04 14:21:45 +05305414 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305415 struct net_device *dev = wdev->netdev;
5416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5417 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5418 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5419 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305420 struct hdd_ext_scan_context *context;
5421 tANI_U32 request_id;
5422 unsigned long rc;
5423 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305425 ENTER();
5426
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427 if (VOS_FTM_MODE == hdd_get_conparam()) {
5428 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5429 return -EINVAL;
5430 }
5431
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 status = wlan_hdd_validate_context(pHddCtx);
5433 if (0 != status)
5434 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305435 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305436 return -EINVAL;
5437 }
Dino Myclee8843b32014-07-04 14:21:45 +05305438 /* check the EXTScan Capability */
5439 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305440 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5441 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305442 {
5443 hddLog(VOS_TRACE_LEVEL_ERROR,
5444 FL("EXTScan not enabled/supported by Firmware"));
5445 return -EINVAL;
5446 }
5447
Dino Mycle6fb96c12014-06-10 11:52:40 +05305448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5449 data, dataLen,
5450 wlan_hdd_extscan_config_policy)) {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5452 return -EINVAL;
5453 }
5454
5455 /* Parse and fetch request Id */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5458 return -EINVAL;
5459 }
5460
Dino Myclee8843b32014-07-04 14:21:45 +05305461 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305462 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464
Dino Myclee8843b32014-07-04 14:21:45 +05305465 reqMsg.sessionId = pAdapter->sessionId;
5466 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305467
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305468 context = &pHddCtx->ext_scan_context;
5469 spin_lock(&hdd_context_lock);
5470 INIT_COMPLETION(context->response_event);
5471 context->request_id = request_id = reqMsg.requestId;
5472 spin_unlock(&hdd_context_lock);
5473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305475 if (!HAL_STATUS_SUCCESS(status)) {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478 return -EINVAL;
5479 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305480
5481 /* request was sent -- wait for the response */
5482 rc = wait_for_completion_timeout(&context->response_event,
5483 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5484 if (!rc) {
5485 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5486 retval = -ETIMEDOUT;
5487 } else {
5488 spin_lock(&hdd_context_lock);
5489 if (context->request_id == request_id)
5490 retval = context->response_status;
5491 else
5492 retval = -EINVAL;
5493 spin_unlock(&hdd_context_lock);
5494 }
5495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305496 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305497 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data, int dataLen)
5503{
5504 int ret = 0;
5505
5506 vos_ssr_protect(__func__);
5507 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5508 vos_ssr_unprotect(__func__);
5509
5510 return ret;
5511}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305512#endif /* WLAN_FEATURE_EXTSCAN */
5513
Atul Mittal115287b2014-07-08 13:26:33 +05305514/*EXT TDLS*/
5515static const struct nla_policy
5516wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5519 .type = NLA_UNSPEC,
5520 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305521 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5522 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5523 {.type = NLA_S32 },
5524 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5525 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5526
5527};
5528
5529static const struct nla_policy
5530wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5531{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305532 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5533 .type = NLA_UNSPEC,
5534 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_state_change_policy[
5540 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5546 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305547 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5548 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5549 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305550
5551};
5552
5553static const struct nla_policy
5554wlan_hdd_tdls_config_get_status_policy[
5555 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5556{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5558 .type = NLA_UNSPEC,
5559 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305560 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5561 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305562 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5563 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5564 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305565
5566};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305567
5568static const struct nla_policy
5569wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5570{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305571 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5572 .type = NLA_UNSPEC,
5573 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574};
5575
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305576static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305578 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579 int data_len)
5580{
5581
5582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5583 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305585 ENTER();
5586
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 return -EINVAL;
5589 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305590 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305592 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305593 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305594 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305595 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 return -ENOTSUPP;
5597 }
5598
5599 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5600 data, data_len, wlan_hdd_mac_config)) {
5601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5602 return -EINVAL;
5603 }
5604
5605 /* Parse and fetch mac address */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5613 VOS_MAC_ADDR_LAST_3_BYTES);
5614
Siddharth Bhal76972212014-10-15 16:22:51 +05305615 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5616
5617 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305618 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5619 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305620 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5621 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5622 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5623 {
5624 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5625 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5626 VOS_MAC_ADDRESS_LEN);
5627 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305629
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305630 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5631 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305633 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305634 return 0;
5635}
5636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data,
5640 int data_len)
5641{
5642 int ret = 0;
5643
5644 vos_ssr_protect(__func__);
5645 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5646 vos_ssr_unprotect(__func__);
5647
5648 return ret;
5649}
5650
5651static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305652 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305653 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305654 int data_len)
5655{
5656 u8 peer[6] = {0};
5657 struct net_device *dev = wdev->netdev;
5658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5660 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5661 eHalStatus ret;
5662 tANI_S32 state;
5663 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 tANI_S32 global_operating_class = 0;
5665 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305666 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305667 int retVal;
5668
5669 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305670
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305671 if (!pAdapter) {
5672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5673 return -EINVAL;
5674 }
5675
Atul Mittal115287b2014-07-08 13:26:33 +05305676 ret = wlan_hdd_validate_context(pHddCtx);
5677 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305679 return -EINVAL;
5680 }
5681 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305683 return -ENOTSUPP;
5684 }
5685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5686 data, data_len,
5687 wlan_hdd_tdls_config_get_status_policy)) {
5688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5689 return -EINVAL;
5690 }
5691
5692 /* Parse and fetch mac address */
5693 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5695 return -EINVAL;
5696 }
5697
5698 memcpy(peer, nla_data(
5699 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5700 sizeof(peer));
5701 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5702
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305703 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305704
Atul Mittal115287b2014-07-08 13:26:33 +05305705 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305706 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305707 NLMSG_HDRLEN);
5708
5709 if (!skb) {
5710 hddLog(VOS_TRACE_LEVEL_ERROR,
5711 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5712 return -EINVAL;
5713 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305714 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 +05305715 reason,
5716 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305717 global_operating_class,
5718 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305719 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305720 if (nla_put_s32(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5722 state) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5725 reason) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5728 global_operating_class) ||
5729 nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5731 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305732
5733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5734 goto nla_put_failure;
5735 }
5736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305737 retVal = cfg80211_vendor_cmd_reply(skb);
5738 EXIT();
5739 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305740
5741nla_put_failure:
5742 kfree_skb(skb);
5743 return -EINVAL;
5744}
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5747 struct wireless_dev *wdev,
5748 const void *data,
5749 int data_len)
5750{
5751 int ret = 0;
5752
5753 vos_ssr_protect(__func__);
5754 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5755 vos_ssr_unprotect(__func__);
5756
5757 return ret;
5758}
5759
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305760static int wlan_hdd_cfg80211_exttdls_callback(
5761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5762 const tANI_U8* mac,
5763#else
5764 tANI_U8* mac,
5765#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305766 tANI_S32 state,
5767 tANI_S32 reason,
5768 void *ctx)
5769{
5770 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305771 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305772 tANI_S32 global_operating_class = 0;
5773 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305774 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305776 ENTER();
5777
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305778 if (!pAdapter) {
5779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5780 return -EINVAL;
5781 }
5782
5783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305784 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305786 return -EINVAL;
5787 }
5788
5789 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305791 return -ENOTSUPP;
5792 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305793 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5795 NULL,
5796#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305797 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5798 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5799 GFP_KERNEL);
5800
5801 if (!skb) {
5802 hddLog(VOS_TRACE_LEVEL_ERROR,
5803 FL("cfg80211_vendor_event_alloc failed"));
5804 return -EINVAL;
5805 }
5806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305807 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5808 reason,
5809 state,
5810 global_operating_class,
5811 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305812 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5813 MAC_ADDR_ARRAY(mac));
5814
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305815 if (nla_put(skb,
5816 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5817 VOS_MAC_ADDR_SIZE, mac) ||
5818 nla_put_s32(skb,
5819 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5820 state) ||
5821 nla_put_s32(skb,
5822 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5823 reason) ||
5824 nla_put_s32(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5826 channel) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5829 global_operating_class)
5830 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5832 goto nla_put_failure;
5833 }
5834
5835 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305836 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305837 return (0);
5838
5839nla_put_failure:
5840 kfree_skb(skb);
5841 return -EINVAL;
5842}
5843
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305844static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305845 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305846 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305847 int data_len)
5848{
5849 u8 peer[6] = {0};
5850 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5853 eHalStatus status;
5854 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305855 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305856 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305857
5858 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305859
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305860 if (!dev) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5862 return -EINVAL;
5863 }
5864
5865 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5866 if (!pAdapter) {
5867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5868 return -EINVAL;
5869 }
5870
Atul Mittal115287b2014-07-08 13:26:33 +05305871 status = wlan_hdd_validate_context(pHddCtx);
5872 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305874 return -EINVAL;
5875 }
5876 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305878 return -ENOTSUPP;
5879 }
5880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5881 data, data_len,
5882 wlan_hdd_tdls_config_enable_policy)) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5884 return -EINVAL;
5885 }
5886
5887 /* Parse and fetch mac address */
5888 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5890 return -EINVAL;
5891 }
5892
5893 memcpy(peer, nla_data(
5894 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5895 sizeof(peer));
5896 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5897
5898 /* Parse and fetch channel */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5901 return -EINVAL;
5902 }
5903 pReqMsg.channel = nla_get_s32(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5906
5907 /* Parse and fetch global operating class */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.global_operating_class = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5915 pReqMsg.global_operating_class);
5916
5917 /* Parse and fetch latency ms */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.max_latency_ms = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5925 pReqMsg.max_latency_ms);
5926
5927 /* Parse and fetch required bandwidth kbps */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5930 return -EINVAL;
5931 }
5932
5933 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5934 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5936 pReqMsg.min_bandwidth_kbps);
5937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305938 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305939 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305940 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305941 wlan_hdd_cfg80211_exttdls_callback);
5942
5943 EXIT();
5944 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305945}
5946
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305947static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5948 struct wireless_dev *wdev,
5949 const void *data,
5950 int data_len)
5951{
5952 int ret = 0;
5953
5954 vos_ssr_protect(__func__);
5955 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5956 vos_ssr_unprotect(__func__);
5957
5958 return ret;
5959}
5960
5961static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305962 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305963 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305964 int data_len)
5965{
5966 u8 peer[6] = {0};
5967 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5969 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5970 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305971 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305972 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305973
5974 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305975
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305976 if (!dev) {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5978 return -EINVAL;
5979 }
5980
5981 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5982 if (!pAdapter) {
5983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5984 return -EINVAL;
5985 }
5986
Atul Mittal115287b2014-07-08 13:26:33 +05305987 status = wlan_hdd_validate_context(pHddCtx);
5988 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305990 return -EINVAL;
5991 }
5992 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305994 return -ENOTSUPP;
5995 }
5996 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5997 data, data_len,
5998 wlan_hdd_tdls_config_disable_policy)) {
5999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6000 return -EINVAL;
6001 }
6002 /* Parse and fetch mac address */
6003 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6005 return -EINVAL;
6006 }
6007
6008 memcpy(peer, nla_data(
6009 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6010 sizeof(peer));
6011 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306013 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6014
6015 EXIT();
6016 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306017}
6018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306019static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6020 struct wireless_dev *wdev,
6021 const void *data,
6022 int data_len)
6023{
6024 int ret = 0;
6025
6026 vos_ssr_protect(__func__);
6027 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6028 vos_ssr_unprotect(__func__);
6029
6030 return ret;
6031}
6032
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306034__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306035 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306036 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306037{
6038 struct net_device *dev = wdev->netdev;
6039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6040 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6041 struct sk_buff *skb = NULL;
6042 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306045 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046
6047 ret = wlan_hdd_validate_context(pHddCtx);
6048 if (0 != ret)
6049 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306050 return ret;
6051 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306052 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6053 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6054 fset |= WIFI_FEATURE_INFRA;
6055 }
6056
6057 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6058 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6059 fset |= WIFI_FEATURE_INFRA_5G;
6060 }
6061
6062#ifdef WLAN_FEATURE_P2P
6063 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6064 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6065 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6066 fset |= WIFI_FEATURE_P2P;
6067 }
6068#endif
6069
6070 /* Soft-AP is supported currently by default */
6071 fset |= WIFI_FEATURE_SOFT_AP;
6072
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306073 /* HOTSPOT is a supplicant feature, enable it by default */
6074 fset |= WIFI_FEATURE_HOTSPOT;
6075
Dasari Srinivas7875a302014-09-26 17:50:57 +05306076#ifdef WLAN_FEATURE_EXTSCAN
6077 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306078 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6079 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6080 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306081 fset |= WIFI_FEATURE_EXTSCAN;
6082 }
6083#endif
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085 if (sme_IsFeatureSupportedByFW(NAN)) {
6086 hddLog(LOG1, FL("NAN is supported by firmware"));
6087 fset |= WIFI_FEATURE_NAN;
6088 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306089
6090 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306091 if (sme_IsFeatureSupportedByFW(RTT) &&
6092 pHddCtx->cfg_ini->enable_rtt_support) {
6093 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 fset |= WIFI_FEATURE_D2AP_RTT;
6095 }
6096
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306097 if (sme_IsFeatureSupportedByFW(RTT3)) {
6098 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6099 fset |= WIFI_FEATURE_RTT3;
6100 }
6101
Dasari Srinivas7875a302014-09-26 17:50:57 +05306102#ifdef FEATURE_WLAN_BATCH_SCAN
6103 if (fset & WIFI_FEATURE_EXTSCAN) {
6104 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6105 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6106 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6107 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6108 fset |= WIFI_FEATURE_BATCH_SCAN;
6109 }
6110#endif
6111
6112#ifdef FEATURE_WLAN_SCAN_PNO
6113 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6114 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6115 hddLog(LOG1, FL("PNO is supported by firmware"));
6116 fset |= WIFI_FEATURE_PNO;
6117 }
6118#endif
6119
6120 /* STA+STA is supported currently by default */
6121 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6122
6123#ifdef FEATURE_WLAN_TDLS
6124 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6125 sme_IsFeatureSupportedByFW(TDLS)) {
6126 hddLog(LOG1, FL("TDLS is supported by firmware"));
6127 fset |= WIFI_FEATURE_TDLS;
6128 }
6129
6130 /* TDLS_OFFCHANNEL is not supported currently by default */
6131#endif
6132
6133#ifdef WLAN_AP_STA_CONCURRENCY
6134 /* AP+STA concurrency is supported currently by default */
6135 fset |= WIFI_FEATURE_AP_STA;
6136#endif
6137
Mukul Sharma5add0532015-08-17 15:57:47 +05306138#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306139 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6140 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306141 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6142 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306143 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306144#endif
6145
Dasari Srinivas7875a302014-09-26 17:50:57 +05306146 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6147 NLMSG_HDRLEN);
6148
6149 if (!skb) {
6150 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6151 return -EINVAL;
6152 }
6153 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6154
6155 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6156 hddLog(LOGE, FL("nla put fail"));
6157 goto nla_put_failure;
6158 }
6159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306160 ret = cfg80211_vendor_cmd_reply(skb);
6161 EXIT();
6162 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306163
6164nla_put_failure:
6165 kfree_skb(skb);
6166 return -EINVAL;
6167}
6168
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306169static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306170wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6171 struct wireless_dev *wdev,
6172 const void *data, int data_len)
6173{
6174 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306175 vos_ssr_protect(__func__);
6176 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6177 vos_ssr_unprotect(__func__);
6178
6179 return ret;
6180}
6181
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306182
6183static const struct
6184nla_policy
6185qca_wlan_vendor_wifi_logger_get_ring_data_policy
6186[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6188 = {.type = NLA_U32 },
6189};
6190
6191static int
6192 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6193 struct wireless_dev *wdev,
6194 const void *data,
6195 int data_len)
6196{
6197 int ret;
6198 VOS_STATUS status;
6199 uint32_t ring_id;
6200 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6201 struct nlattr *tb
6202 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6203
6204 ENTER();
6205
6206 ret = wlan_hdd_validate_context(hdd_ctx);
6207 if (0 != ret) {
6208 return ret;
6209 }
6210
6211 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6212 data, data_len,
6213 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6214 hddLog(LOGE, FL("Invalid attribute"));
6215 return -EINVAL;
6216 }
6217
6218 /* Parse and fetch ring id */
6219 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6220 hddLog(LOGE, FL("attr ATTR failed"));
6221 return -EINVAL;
6222 }
6223
6224 ring_id = nla_get_u32(
6225 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6226
6227 hddLog(LOG1, FL("Bug report triggered by framework"));
6228
6229 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6230 WLAN_LOG_INDICATOR_FRAMEWORK,
6231 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306232 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306233 );
6234 if (VOS_STATUS_SUCCESS != status) {
6235 hddLog(LOGE, FL("Failed to trigger bug report"));
6236
6237 return -EINVAL;
6238 }
6239
6240 return 0;
6241
6242
6243}
6244
6245
6246static int
6247 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6248 struct wireless_dev *wdev,
6249 const void *data,
6250 int data_len)
6251{
6252 int ret = 0;
6253
6254 vos_ssr_protect(__func__);
6255 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6256 wdev, data, data_len);
6257 vos_ssr_unprotect(__func__);
6258
6259 return ret;
6260
6261}
6262
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306263#define MAX_CONCURRENT_MATRIX \
6264 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6265#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6266 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6267static const struct nla_policy
6268wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6269 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6270};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306272static int
6273__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306274 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306275 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306276{
6277 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6278 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306279 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306280 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6282 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283
6284 ENTER();
6285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306286 ret = wlan_hdd_validate_context(pHddCtx);
6287 if (0 != ret)
6288 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306289 return ret;
6290 }
6291
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306292 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6293 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294 hddLog(LOGE, FL("Invalid ATTR"));
6295 return -EINVAL;
6296 }
6297
6298 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306299 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 hddLog(LOGE, FL("Attr max feature set size failed"));
6301 return -EINVAL;
6302 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306303 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6305
6306 /* Fill feature combination matrix */
6307 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306308 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6309 WIFI_FEATURE_P2P;
6310
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306311 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6312 WIFI_FEATURE_SOFT_AP;
6313
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6315 WIFI_FEATURE_SOFT_AP;
6316
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_SOFT_AP |
6319 WIFI_FEATURE_P2P;
6320
6321 /* Add more feature combinations here */
6322
6323 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6324 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6325 hddLog(LOG1, "Feature set matrix");
6326 for (i = 0; i < feature_sets; i++)
6327 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6328
6329 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6330 sizeof(u32) * feature_sets +
6331 NLMSG_HDRLEN);
6332
6333 if (reply_skb) {
6334 if (nla_put_u32(reply_skb,
6335 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6336 feature_sets) ||
6337 nla_put(reply_skb,
6338 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6339 sizeof(u32) * feature_sets, feature_set_matrix)) {
6340 hddLog(LOGE, FL("nla put fail"));
6341 kfree_skb(reply_skb);
6342 return -EINVAL;
6343 }
6344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306345 ret = cfg80211_vendor_cmd_reply(reply_skb);
6346 EXIT();
6347 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306348 }
6349 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6350 return -ENOMEM;
6351
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306352}
6353
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306354#undef MAX_CONCURRENT_MATRIX
6355#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6356
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306357static int
6358wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6359 struct wireless_dev *wdev,
6360 const void *data, int data_len)
6361{
6362 int ret = 0;
6363
6364 vos_ssr_protect(__func__);
6365 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6366 data_len);
6367 vos_ssr_unprotect(__func__);
6368
6369 return ret;
6370}
6371
c_manjeecfd1efb2015-09-25 19:32:34 +05306372
6373static int
6374__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6375 struct wireless_dev *wdev,
6376 const void *data, int data_len)
6377{
6378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6379 int ret;
6380 ENTER();
6381
6382 ret = wlan_hdd_validate_context(pHddCtx);
6383 if (0 != ret)
6384 {
6385 return ret;
6386 }
6387
6388 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6389 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306392 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306393 }
6394 /*call common API for FW mem dump req*/
6395 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6396
Abhishek Singhc783fa72015-12-09 18:07:34 +05306397 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306398 {
6399 /*indicate to userspace the status of fw mem dump */
6400 wlan_indicate_mem_dump_complete(true);
6401 }
6402 else
6403 {
6404 /*else send failure to userspace */
6405 wlan_indicate_mem_dump_complete(false);
6406 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306407 EXIT();
6408 return ret;
6409}
6410
6411/**
6412 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6413 * @wiphy: pointer to wireless wiphy structure.
6414 * @wdev: pointer to wireless_dev structure.
6415 * @data: Pointer to the NL data.
6416 * @data_len:Length of @data
6417 *
6418 * This is called when wlan driver needs to get the firmware memory dump
6419 * via vendor specific command.
6420 *
6421 * Return: 0 on success, error number otherwise.
6422 */
6423
6424static int
6425wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6426 struct wireless_dev *wdev,
6427 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306428{
6429 int ret = 0;
6430 vos_ssr_protect(__func__);
6431 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6432 data_len);
6433 vos_ssr_unprotect(__func__);
6434 return ret;
6435}
c_manjeecfd1efb2015-09-25 19:32:34 +05306436
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437static const struct
6438nla_policy
6439qca_wlan_vendor_wifi_logger_start_policy
6440[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6441 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6442 = {.type = NLA_U32 },
6443 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6444 = {.type = NLA_U32 },
6445 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6446 = {.type = NLA_U32 },
6447};
6448
6449/**
6450 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6451 * or disable the collection of packet statistics from the firmware
6452 * @wiphy: WIPHY structure pointer
6453 * @wdev: Wireless device structure pointer
6454 * @data: Pointer to the data received
6455 * @data_len: Length of the data received
6456 *
6457 * This function is used to enable or disable the collection of packet
6458 * statistics from the firmware
6459 *
6460 * Return: 0 on success and errno on failure
6461 */
6462static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6463 struct wireless_dev *wdev,
6464 const void *data,
6465 int data_len)
6466{
6467 eHalStatus status;
6468 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6470 tAniWifiStartLog start_log;
6471
6472 status = wlan_hdd_validate_context(hdd_ctx);
6473 if (0 != status) {
6474 return -EINVAL;
6475 }
6476
6477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6478 data, data_len,
6479 qca_wlan_vendor_wifi_logger_start_policy)) {
6480 hddLog(LOGE, FL("Invalid attribute"));
6481 return -EINVAL;
6482 }
6483
6484 /* Parse and fetch ring id */
6485 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6486 hddLog(LOGE, FL("attr ATTR failed"));
6487 return -EINVAL;
6488 }
6489 start_log.ringId = nla_get_u32(
6490 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6491 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6492
6493 /* Parse and fetch verbose level */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6495 hddLog(LOGE, FL("attr verbose_level failed"));
6496 return -EINVAL;
6497 }
6498 start_log.verboseLevel = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6500 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6501
6502 /* Parse and fetch flag */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6504 hddLog(LOGE, FL("attr flag failed"));
6505 return -EINVAL;
6506 }
6507 start_log.flag = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6509 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6510
6511 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306512 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6513 !vos_isPktStatsEnabled()))
6514
Sushant Kaushik8e644982015-09-23 12:18:54 +05306515 {
6516 hddLog(LOGE, FL("per pkt stats not enabled"));
6517 return -EINVAL;
6518 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306519
Sushant Kaushik33200572015-08-05 16:46:20 +05306520 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306521 return 0;
6522}
6523
6524/**
6525 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6526 * or disable the collection of packet statistics from the firmware
6527 * @wiphy: WIPHY structure pointer
6528 * @wdev: Wireless device structure pointer
6529 * @data: Pointer to the data received
6530 * @data_len: Length of the data received
6531 *
6532 * This function is used to enable or disable the collection of packet
6533 * statistics from the firmware
6534 *
6535 * Return: 0 on success and errno on failure
6536 */
6537static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6538 struct wireless_dev *wdev,
6539 const void *data,
6540 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306541{
6542 int ret = 0;
6543
6544 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306545
6546 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6547 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306548 vos_ssr_unprotect(__func__);
6549
6550 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306551}
6552
6553
Agarwal Ashish738843c2014-09-25 12:27:56 +05306554static const struct nla_policy
6555wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6556 +1] =
6557{
6558 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6559};
6560
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306561static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306562 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306563 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564 int data_len)
6565{
6566 struct net_device *dev = wdev->netdev;
6567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6568 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6570 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6571 eHalStatus status;
6572 u32 dfsFlag = 0;
6573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306574 ENTER();
6575
Agarwal Ashish738843c2014-09-25 12:27:56 +05306576 status = wlan_hdd_validate_context(pHddCtx);
6577 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306578 return -EINVAL;
6579 }
6580 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6581 data, data_len,
6582 wlan_hdd_set_no_dfs_flag_config_policy)) {
6583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6584 return -EINVAL;
6585 }
6586
6587 /* Parse and fetch required bandwidth kbps */
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6590 return -EINVAL;
6591 }
6592
6593 dfsFlag = nla_get_u32(
6594 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6595 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6596 dfsFlag);
6597
6598 pHddCtx->disable_dfs_flag = dfsFlag;
6599
6600 sme_disable_dfs_channel(hHal, dfsFlag);
6601 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306602
6603 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306604 return 0;
6605}
Atul Mittal115287b2014-07-08 13:26:33 +05306606
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306607static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6608 struct wireless_dev *wdev,
6609 const void *data,
6610 int data_len)
6611{
6612 int ret = 0;
6613
6614 vos_ssr_protect(__func__);
6615 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6616 vos_ssr_unprotect(__func__);
6617
6618 return ret;
6619
6620}
6621
Mukul Sharma2a271632014-10-13 14:59:01 +05306622const struct
6623nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6624{
6625 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306626 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6627 .type = NLA_UNSPEC,
6628 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306629};
6630
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306631static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306632 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306633{
6634
6635 u8 bssid[6] = {0};
6636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6637 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6638 eHalStatus status = eHAL_STATUS_SUCCESS;
6639 v_U32_t isFwrRoamEnabled = FALSE;
6640 int ret;
6641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306642 ENTER();
6643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306644 ret = wlan_hdd_validate_context(pHddCtx);
6645 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306646 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306647 }
6648
6649 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6650 data, data_len,
6651 qca_wlan_vendor_attr);
6652 if (ret){
6653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6654 return -EINVAL;
6655 }
6656
6657 /* Parse and fetch Enable flag */
6658 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6660 return -EINVAL;
6661 }
6662
6663 isFwrRoamEnabled = nla_get_u32(
6664 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6665
6666 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6667
6668 /* Parse and fetch bssid */
6669 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6671 return -EINVAL;
6672 }
6673
6674 memcpy(bssid, nla_data(
6675 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6676 sizeof(bssid));
6677 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6678
6679 //Update roaming
6680 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306681 if (!HAL_STATUS_SUCCESS(status)) {
6682 hddLog(LOGE,
6683 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6684 return -EINVAL;
6685 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306686 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306687 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306688}
6689
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306690static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6691 struct wireless_dev *wdev, const void *data, int data_len)
6692{
6693 int ret = 0;
6694
6695 vos_ssr_protect(__func__);
6696 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6697 vos_ssr_unprotect(__func__);
6698
6699 return ret;
6700}
6701
Sushant Kaushik847890c2015-09-28 16:05:17 +05306702static const struct
6703nla_policy
6704qca_wlan_vendor_get_wifi_info_policy[
6705 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6706 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6707 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6708};
6709
6710
6711/**
6712 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6713 * @wiphy: pointer to wireless wiphy structure.
6714 * @wdev: pointer to wireless_dev structure.
6715 * @data: Pointer to the data to be passed via vendor interface
6716 * @data_len:Length of the data to be passed
6717 *
6718 * This is called when wlan driver needs to send wifi driver related info
6719 * (driver/fw version) to the user space application upon request.
6720 *
6721 * Return: Return the Success or Failure code.
6722 */
6723static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6724 struct wireless_dev *wdev,
6725 const void *data, int data_len)
6726{
6727 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6728 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6729 tSirVersionString version;
6730 uint32 version_len;
6731 uint8 attr;
6732 int status;
6733 struct sk_buff *reply_skb = NULL;
6734
6735 if (VOS_FTM_MODE == hdd_get_conparam()) {
6736 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6737 return -EINVAL;
6738 }
6739
6740 status = wlan_hdd_validate_context(hdd_ctx);
6741 if (0 != status) {
6742 hddLog(LOGE, FL("HDD context is not valid"));
6743 return -EINVAL;
6744 }
6745
6746 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6747 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6748 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6749 return -EINVAL;
6750 }
6751
6752 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6753 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6754 QWLAN_VERSIONSTR);
6755 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6756 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6757 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6758 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6759 hdd_ctx->fw_Version);
6760 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6761 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6762 } else {
6763 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6764 return -EINVAL;
6765 }
6766
6767 version_len = strlen(version);
6768 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6769 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6770 if (!reply_skb) {
6771 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6772 return -ENOMEM;
6773 }
6774
6775 if (nla_put(reply_skb, attr, version_len, version)) {
6776 hddLog(LOGE, FL("nla put fail"));
6777 kfree_skb(reply_skb);
6778 return -EINVAL;
6779 }
6780
6781 return cfg80211_vendor_cmd_reply(reply_skb);
6782}
6783
6784/**
6785 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6786 * @wiphy: pointer to wireless wiphy structure.
6787 * @wdev: pointer to wireless_dev structure.
6788 * @data: Pointer to the data to be passed via vendor interface
6789 * @data_len:Length of the data to be passed
6790 * @data_len: Length of the data received
6791 *
6792 * This function is used to enable or disable the collection of packet
6793 * statistics from the firmware
6794 *
6795 * Return: 0 on success and errno on failure
6796 */
6797
6798static int
6799wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data, int data_len)
6802
6803
6804{
6805 int ret = 0;
6806
6807 vos_ssr_protect(__func__);
6808 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6809 wdev, data, data_len);
6810 vos_ssr_unprotect(__func__);
6811
6812 return ret;
6813}
6814
6815
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306816/*
6817 * define short names for the global vendor params
6818 * used by __wlan_hdd_cfg80211_monitor_rssi()
6819 */
6820#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6821#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6822#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6823#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6824#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6825
6826/**---------------------------------------------------------------------------
6827
6828 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6829 monitor start is completed successfully.
6830
6831 \return - None
6832
6833 --------------------------------------------------------------------------*/
6834void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6835{
6836 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6837
6838 if (NULL == pHddCtx)
6839 {
6840 hddLog(VOS_TRACE_LEVEL_ERROR,
6841 "%s: HDD context is NULL",__func__);
6842 return;
6843 }
6844
6845 if (VOS_STATUS_SUCCESS == status)
6846 {
6847 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6848 }
6849 else
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6852 }
6853
6854 return;
6855}
6856
6857/**---------------------------------------------------------------------------
6858
6859 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6860 stop is completed successfully.
6861
6862 \return - None
6863
6864 --------------------------------------------------------------------------*/
6865void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6866{
6867 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6868
6869 if (NULL == pHddCtx)
6870 {
6871 hddLog(VOS_TRACE_LEVEL_ERROR,
6872 "%s: HDD context is NULL",__func__);
6873 return;
6874 }
6875
6876 if (VOS_STATUS_SUCCESS == status)
6877 {
6878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6879 }
6880 else
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6883 }
6884
6885 return;
6886}
6887
6888/**
6889 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6890 * @wiphy: Pointer to wireless phy
6891 * @wdev: Pointer to wireless device
6892 * @data: Pointer to data
6893 * @data_len: Data length
6894 *
6895 * Return: 0 on success, negative errno on failure
6896 */
6897
6898static int
6899__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6900 struct wireless_dev *wdev,
6901 const void *data,
6902 int data_len)
6903{
6904 struct net_device *dev = wdev->netdev;
6905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6906 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6907 hdd_station_ctx_t *pHddStaCtx;
6908 struct nlattr *tb[PARAM_MAX + 1];
6909 tpSirRssiMonitorReq pReq;
6910 eHalStatus status;
6911 int ret;
6912 uint32_t control;
6913 static const struct nla_policy policy[PARAM_MAX + 1] = {
6914 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6915 [PARAM_CONTROL] = { .type = NLA_U32 },
6916 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6917 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6918 };
6919
6920 ENTER();
6921
6922 ret = wlan_hdd_validate_context(hdd_ctx);
6923 if (0 != ret) {
6924 return -EINVAL;
6925 }
6926
6927 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6928 hddLog(LOGE, FL("Not in Connected state!"));
6929 return -ENOTSUPP;
6930 }
6931
6932 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6933 hddLog(LOGE, FL("Invalid ATTR"));
6934 return -EINVAL;
6935 }
6936
6937 if (!tb[PARAM_REQUEST_ID]) {
6938 hddLog(LOGE, FL("attr request id failed"));
6939 return -EINVAL;
6940 }
6941
6942 if (!tb[PARAM_CONTROL]) {
6943 hddLog(LOGE, FL("attr control failed"));
6944 return -EINVAL;
6945 }
6946
6947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6948
6949 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6950 if(NULL == pReq)
6951 {
6952 hddLog(LOGE,
6953 FL("vos_mem_alloc failed "));
6954 return eHAL_STATUS_FAILED_ALLOC;
6955 }
6956 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6957
6958 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6959 pReq->sessionId = pAdapter->sessionId;
6960 pReq->rssiMonitorCbContext = hdd_ctx;
6961 control = nla_get_u32(tb[PARAM_CONTROL]);
6962 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6963
6964 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6965 pReq->requestId, pReq->sessionId, control);
6966
6967 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6968 if (!tb[PARAM_MIN_RSSI]) {
6969 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306970 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306971 }
6972
6973 if (!tb[PARAM_MAX_RSSI]) {
6974 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306975 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306976 }
6977
6978 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6979 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6980 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6981
6982 if (!(pReq->minRssi < pReq->maxRssi)) {
6983 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6984 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6988 pReq->minRssi, pReq->maxRssi);
6989 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6990
6991 }
6992 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6993 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6994 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6995 }
6996 else {
6997 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306998 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306999 }
7000
7001 if (!HAL_STATUS_SUCCESS(status)) {
7002 hddLog(LOGE,
7003 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307004 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307005 }
7006
7007 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008fail:
7009 vos_mem_free(pReq);
7010 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307011}
7012
7013/*
7014 * done with short names for the global vendor params
7015 * used by __wlan_hdd_cfg80211_monitor_rssi()
7016 */
7017#undef PARAM_MAX
7018#undef PARAM_CONTROL
7019#undef PARAM_REQUEST_ID
7020#undef PARAM_MAX_RSSI
7021#undef PARAM_MIN_RSSI
7022
7023/**
7024 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7025 * @wiphy: wiphy structure pointer
7026 * @wdev: Wireless device structure pointer
7027 * @data: Pointer to the data received
7028 * @data_len: Length of @data
7029 *
7030 * Return: 0 on success; errno on failure
7031 */
7032static int
7033wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7034 const void *data, int data_len)
7035{
7036 int ret;
7037
7038 vos_ssr_protect(__func__);
7039 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7040 vos_ssr_unprotect(__func__);
7041
7042 return ret;
7043}
7044
7045/**
7046 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7047 * @hddctx: HDD context
7048 * @data: rssi breached event data
7049 *
7050 * This function reads the rssi breached event %data and fill in the skb with
7051 * NL attributes and send up the NL event.
7052 * This callback execute in atomic context and must not invoke any
7053 * blocking calls.
7054 *
7055 * Return: none
7056 */
7057void hdd_rssi_threshold_breached_cb(void *hddctx,
7058 struct rssi_breach_event *data)
7059{
7060 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7061 int status;
7062 struct sk_buff *skb;
7063
7064 ENTER();
7065 status = wlan_hdd_validate_context(pHddCtx);
7066
7067 if (0 != status) {
7068 return;
7069 }
7070
7071 if (!data) {
7072 hddLog(LOGE, FL("data is null"));
7073 return;
7074 }
7075
7076 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7078 NULL,
7079#endif
7080 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7081 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7082 GFP_KERNEL);
7083
7084 if (!skb) {
7085 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7086 return;
7087 }
7088
7089 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7090 data->request_id, data->curr_rssi);
7091 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7092 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7093
7094 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7095 data->request_id) ||
7096 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7097 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7098 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7099 data->curr_rssi)) {
7100 hddLog(LOGE, FL("nla put fail"));
7101 goto fail;
7102 }
7103
7104 cfg80211_vendor_event(skb, GFP_KERNEL);
7105 return;
7106
7107fail:
7108 kfree_skb(skb);
7109 return;
7110}
7111
7112
7113
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307114/**
7115 * __wlan_hdd_cfg80211_setband() - set band
7116 * @wiphy: Pointer to wireless phy
7117 * @wdev: Pointer to wireless device
7118 * @data: Pointer to data
7119 * @data_len: Data length
7120 *
7121 * Return: 0 on success, negative errno on failure
7122 */
7123static int
7124__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7125 struct wireless_dev *wdev,
7126 const void *data,
7127 int data_len)
7128{
7129 struct net_device *dev = wdev->netdev;
7130 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7131 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7132 int ret;
7133 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7134 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7135
7136 ENTER();
7137
7138 ret = wlan_hdd_validate_context(hdd_ctx);
7139 if (0 != ret) {
7140 hddLog(LOGE, FL("HDD context is not valid"));
7141 return ret;
7142 }
7143
7144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7145 policy)) {
7146 hddLog(LOGE, FL("Invalid ATTR"));
7147 return -EINVAL;
7148 }
7149
7150 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7151 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7152 return -EINVAL;
7153 }
7154
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307155 hdd_ctx->isSetBandByNL = TRUE;
7156 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307157 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307158 hdd_ctx->isSetBandByNL = FALSE;
7159
7160 EXIT();
7161 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307162}
7163
7164/**
7165 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7166 * @wiphy: wiphy structure pointer
7167 * @wdev: Wireless device structure pointer
7168 * @data: Pointer to the data received
7169 * @data_len: Length of @data
7170 *
7171 * Return: 0 on success; errno on failure
7172 */
7173static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7174 struct wireless_dev *wdev,
7175 const void *data,
7176 int data_len)
7177{
7178 int ret = 0;
7179
7180 vos_ssr_protect(__func__);
7181 ret = __wlan_hdd_cfg80211_setband(wiphy,
7182 wdev, data, data_len);
7183 vos_ssr_unprotect(__func__);
7184
7185 return ret;
7186}
7187
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307188#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7189/**
7190 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7191 * @hdd_ctx: HDD context
7192 * @request_id: [input] request id
7193 * @pattern_id: [output] pattern id
7194 *
7195 * This function loops through request id to pattern id array
7196 * if the slot is available, store the request id and return pattern id
7197 * if entry exists, return the pattern id
7198 *
7199 * Return: 0 on success and errno on failure
7200 */
7201static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7202 uint32_t request_id,
7203 uint8_t *pattern_id)
7204{
7205 uint32_t i;
7206
7207 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7208 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7209 {
7210 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7211 {
7212 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7213 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7214 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7215 return 0;
7216 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7217 request_id) {
7218 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7219 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7220 return 0;
7221 }
7222 }
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return -EINVAL;
7225}
7226
7227/**
7228 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7229 * @hdd_ctx: HDD context
7230 * @request_id: [input] request id
7231 * @pattern_id: [output] pattern id
7232 *
7233 * This function loops through request id to pattern id array
7234 * reset request id to 0 (slot available again) and
7235 * return pattern id
7236 *
7237 * Return: 0 on success and errno on failure
7238 */
7239static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7240 uint32_t request_id,
7241 uint8_t *pattern_id)
7242{
7243 uint32_t i;
7244
7245 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7246 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7247 {
7248 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7249 {
7250 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7251 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7252 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7253 return 0;
7254 }
7255 }
7256 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7257 return -EINVAL;
7258}
7259
7260
7261/*
7262 * define short names for the global vendor params
7263 * used by __wlan_hdd_cfg80211_offloaded_packets()
7264 */
7265#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7266#define PARAM_REQUEST_ID \
7267 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7268#define PARAM_CONTROL \
7269 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7270#define PARAM_IP_PACKET \
7271 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7272#define PARAM_SRC_MAC_ADDR \
7273 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7274#define PARAM_DST_MAC_ADDR \
7275 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7276#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7277
7278/**
7279 * wlan_hdd_add_tx_ptrn() - add tx pattern
7280 * @adapter: adapter pointer
7281 * @hdd_ctx: hdd context
7282 * @tb: nl attributes
7283 *
7284 * This function reads the NL attributes and forms a AddTxPtrn message
7285 * posts it to SME.
7286 *
7287 */
7288static int
7289wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7290 struct nlattr **tb)
7291{
7292 struct sSirAddPeriodicTxPtrn *add_req;
7293 eHalStatus status;
7294 uint32_t request_id, ret, len;
7295 uint8_t pattern_id = 0;
7296 v_MACADDR_t dst_addr;
7297 uint16_t eth_type = htons(ETH_P_IP);
7298
7299 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7300 {
7301 hddLog(LOGE, FL("Not in Connected state!"));
7302 return -ENOTSUPP;
7303 }
7304
7305 add_req = vos_mem_malloc(sizeof(*add_req));
7306 if (!add_req)
7307 {
7308 hddLog(LOGE, FL("memory allocation failed"));
7309 return -ENOMEM;
7310 }
7311
7312 /* Parse and fetch request Id */
7313 if (!tb[PARAM_REQUEST_ID])
7314 {
7315 hddLog(LOGE, FL("attr request id failed"));
7316 goto fail;
7317 }
7318
7319 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7320 hddLog(LOG1, FL("Request Id: %u"), request_id);
7321 if (request_id == 0)
7322 {
7323 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307324 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307325 }
7326
7327 if (!tb[PARAM_PERIOD])
7328 {
7329 hddLog(LOGE, FL("attr period failed"));
7330 goto fail;
7331 }
7332 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7333 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7334 if (add_req->usPtrnIntervalMs == 0)
7335 {
7336 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7337 goto fail;
7338 }
7339
7340 if (!tb[PARAM_SRC_MAC_ADDR])
7341 {
7342 hddLog(LOGE, FL("attr source mac address failed"));
7343 goto fail;
7344 }
7345 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7346 VOS_MAC_ADDR_SIZE);
7347 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7348 MAC_ADDR_ARRAY(add_req->macAddress));
7349
7350 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7351 VOS_MAC_ADDR_SIZE))
7352 {
7353 hddLog(LOGE,
7354 FL("input src mac address and connected ap bssid are different"));
7355 goto fail;
7356 }
7357
7358 if (!tb[PARAM_DST_MAC_ADDR])
7359 {
7360 hddLog(LOGE, FL("attr dst mac address failed"));
7361 goto fail;
7362 }
7363 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7364 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7365 MAC_ADDR_ARRAY(dst_addr.bytes));
7366
7367 if (!tb[PARAM_IP_PACKET])
7368 {
7369 hddLog(LOGE, FL("attr ip packet failed"));
7370 goto fail;
7371 }
7372 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7373 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7374
7375 if (add_req->ucPtrnSize < 0 ||
7376 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7377 HDD_ETH_HEADER_LEN))
7378 {
7379 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7380 add_req->ucPtrnSize);
7381 goto fail;
7382 }
7383
7384 len = 0;
7385 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7386 len += VOS_MAC_ADDR_SIZE;
7387 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7388 VOS_MAC_ADDR_SIZE);
7389 len += VOS_MAC_ADDR_SIZE;
7390 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7391 len += 2;
7392
7393 /*
7394 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7395 * ------------------------------------------------------------
7396 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7397 * ------------------------------------------------------------
7398 */
7399 vos_mem_copy(&add_req->ucPattern[len],
7400 nla_data(tb[PARAM_IP_PACKET]),
7401 add_req->ucPtrnSize);
7402 add_req->ucPtrnSize += len;
7403
7404 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7405 add_req->ucPattern, add_req->ucPtrnSize);
7406
7407 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7408 if (ret)
7409 {
7410 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7411 goto fail;
7412 }
7413 add_req->ucPtrnId = pattern_id;
7414 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7415
7416 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7417 if (!HAL_STATUS_SUCCESS(status))
7418 {
7419 hddLog(LOGE,
7420 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7421 goto fail;
7422 }
7423
7424 EXIT();
7425 vos_mem_free(add_req);
7426 return 0;
7427
7428fail:
7429 vos_mem_free(add_req);
7430 return -EINVAL;
7431}
7432
7433/**
7434 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7435 * @adapter: adapter pointer
7436 * @hdd_ctx: hdd context
7437 * @tb: nl attributes
7438 *
7439 * This function reads the NL attributes and forms a DelTxPtrn message
7440 * posts it to SME.
7441 *
7442 */
7443static int
7444wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7445 struct nlattr **tb)
7446{
7447 struct sSirDelPeriodicTxPtrn *del_req;
7448 eHalStatus status;
7449 uint32_t request_id, ret;
7450 uint8_t pattern_id = 0;
7451
7452 /* Parse and fetch request Id */
7453 if (!tb[PARAM_REQUEST_ID])
7454 {
7455 hddLog(LOGE, FL("attr request id failed"));
7456 return -EINVAL;
7457 }
7458 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7459 if (request_id == 0)
7460 {
7461 hddLog(LOGE, FL("request_id cannot be zero"));
7462 return -EINVAL;
7463 }
7464
7465 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7466 if (ret)
7467 {
7468 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7469 return -EINVAL;
7470 }
7471
7472 del_req = vos_mem_malloc(sizeof(*del_req));
7473 if (!del_req)
7474 {
7475 hddLog(LOGE, FL("memory allocation failed"));
7476 return -ENOMEM;
7477 }
7478
7479 vos_mem_set(del_req, sizeof(*del_req), 0);
7480 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7481 VOS_MAC_ADDR_SIZE);
7482 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7483 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7484 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7485 request_id, pattern_id, del_req->ucPatternIdBitmap);
7486
7487 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7488 if (!HAL_STATUS_SUCCESS(status))
7489 {
7490 hddLog(LOGE,
7491 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7492 goto fail;
7493 }
7494
7495 EXIT();
7496 vos_mem_free(del_req);
7497 return 0;
7498
7499fail:
7500 vos_mem_free(del_req);
7501 return -EINVAL;
7502}
7503
7504
7505/**
7506 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7507 * @wiphy: Pointer to wireless phy
7508 * @wdev: Pointer to wireless device
7509 * @data: Pointer to data
7510 * @data_len: Data length
7511 *
7512 * Return: 0 on success, negative errno on failure
7513 */
7514static int
7515__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7516 struct wireless_dev *wdev,
7517 const void *data,
7518 int data_len)
7519{
7520 struct net_device *dev = wdev->netdev;
7521 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7523 struct nlattr *tb[PARAM_MAX + 1];
7524 uint8_t control;
7525 int ret;
7526 static const struct nla_policy policy[PARAM_MAX + 1] =
7527 {
7528 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7529 [PARAM_CONTROL] = { .type = NLA_U32 },
7530 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7531 .len = VOS_MAC_ADDR_SIZE },
7532 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7533 .len = VOS_MAC_ADDR_SIZE },
7534 [PARAM_PERIOD] = { .type = NLA_U32 },
7535 };
7536
7537 ENTER();
7538
7539 ret = wlan_hdd_validate_context(hdd_ctx);
7540 if (0 != ret)
7541 {
7542 hddLog(LOGE, FL("HDD context is not valid"));
7543 return ret;
7544 }
7545
7546 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7547 {
7548 hddLog(LOGE,
7549 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7550 return -ENOTSUPP;
7551 }
7552
7553 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7554 {
7555 hddLog(LOGE, FL("Invalid ATTR"));
7556 return -EINVAL;
7557 }
7558
7559 if (!tb[PARAM_CONTROL])
7560 {
7561 hddLog(LOGE, FL("attr control failed"));
7562 return -EINVAL;
7563 }
7564 control = nla_get_u32(tb[PARAM_CONTROL]);
7565 hddLog(LOG1, FL("Control: %d"), control);
7566
7567 if (control == WLAN_START_OFFLOADED_PACKETS)
7568 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7569 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7570 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7571 else
7572 {
7573 hddLog(LOGE, FL("Invalid control: %d"), control);
7574 return -EINVAL;
7575 }
7576}
7577
7578/*
7579 * done with short names for the global vendor params
7580 * used by __wlan_hdd_cfg80211_offloaded_packets()
7581 */
7582#undef PARAM_MAX
7583#undef PARAM_REQUEST_ID
7584#undef PARAM_CONTROL
7585#undef PARAM_IP_PACKET
7586#undef PARAM_SRC_MAC_ADDR
7587#undef PARAM_DST_MAC_ADDR
7588#undef PARAM_PERIOD
7589
7590/**
7591 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7592 * @wiphy: wiphy structure pointer
7593 * @wdev: Wireless device structure pointer
7594 * @data: Pointer to the data received
7595 * @data_len: Length of @data
7596 *
7597 * Return: 0 on success; errno on failure
7598 */
7599static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7600 struct wireless_dev *wdev,
7601 const void *data,
7602 int data_len)
7603{
7604 int ret = 0;
7605
7606 vos_ssr_protect(__func__);
7607 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7608 wdev, data, data_len);
7609 vos_ssr_unprotect(__func__);
7610
7611 return ret;
7612}
7613#endif
7614
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307615static const struct
7616nla_policy
7617qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307618 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7619 .type = NLA_BINARY,
7620 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621};
7622
7623/**
7624 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7625 * get link properties like nss, rate flags and operating frequency for
7626 * the connection with the given peer.
7627 * @wiphy: WIPHY structure pointer
7628 * @wdev: Wireless device structure pointer
7629 * @data: Pointer to the data received
7630 * @data_len: Length of the data received
7631 *
7632 * This function return the above link properties on success.
7633 *
7634 * Return: 0 on success and errno on failure
7635 */
7636static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7637 struct wireless_dev *wdev,
7638 const void *data,
7639 int data_len)
7640{
7641 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7642 struct net_device *dev = wdev->netdev;
7643 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7644 hdd_station_ctx_t *hdd_sta_ctx;
7645 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7646 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7647 uint32_t sta_id;
7648 struct sk_buff *reply_skb;
7649 uint32_t rate_flags = 0;
7650 uint8_t nss;
7651 uint8_t final_rate_flags = 0;
7652 uint32_t freq;
7653 v_CONTEXT_t pVosContext = NULL;
7654 ptSapContext pSapCtx = NULL;
7655
7656 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7658 return -EINVAL;
7659 }
7660
7661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7662 qca_wlan_vendor_attr_policy)) {
7663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7664 return -EINVAL;
7665 }
7666
7667 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7668 hddLog(VOS_TRACE_LEVEL_ERROR,
7669 FL("Attribute peerMac not provided for mode=%d"),
7670 adapter->device_mode);
7671 return -EINVAL;
7672 }
7673
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307674 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("Attribute peerMac is invalid=%d"),
7677 adapter->device_mode);
7678 return -EINVAL;
7679 }
7680
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7682 sizeof(peer_mac));
7683 hddLog(VOS_TRACE_LEVEL_INFO,
7684 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7685 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7686
7687 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7688 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7689 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7690 if ((hdd_sta_ctx->conn_info.connState !=
7691 eConnectionState_Associated) ||
7692 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7693 VOS_MAC_ADDRESS_LEN)) {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
7695 FL("Not Associated to mac "MAC_ADDRESS_STR),
7696 MAC_ADDR_ARRAY(peer_mac));
7697 return -EINVAL;
7698 }
7699
7700 nss = 1; //pronto supports only one spatial stream
7701 freq = vos_chan_to_freq(
7702 hdd_sta_ctx->conn_info.operationChannel);
7703 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7704
7705 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7706 adapter->device_mode == WLAN_HDD_SOFTAP) {
7707
7708 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7709 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7710 if(pSapCtx == NULL){
7711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7712 FL("psapCtx is NULL"));
7713 return -ENOENT;
7714 }
7715
7716
7717 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7718 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7719 !vos_is_macaddr_broadcast(
7720 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7721 vos_mem_compare(
7722 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7723 peer_mac, VOS_MAC_ADDRESS_LEN))
7724 break;
7725 }
7726
7727 if (WLAN_MAX_STA_COUNT == sta_id) {
7728 hddLog(VOS_TRACE_LEVEL_ERROR,
7729 FL("No active peer with mac="MAC_ADDRESS_STR),
7730 MAC_ADDR_ARRAY(peer_mac));
7731 return -EINVAL;
7732 }
7733
7734 nss = 1; //pronto supports only one spatial stream
7735 freq = vos_chan_to_freq(
7736 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7737 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7738 } else {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(peer_mac));
7742 return -EINVAL;
7743 }
7744
7745 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7746 if (rate_flags & eHAL_TX_RATE_VHT80) {
7747 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307748#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7749 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307750 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307751#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7753 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307754#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7755 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307756 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307758 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7759 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7760 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7761 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7763 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307764 if (rate_flags & eHAL_TX_RATE_HT40)
7765 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 }
7768
7769 if (rate_flags & eHAL_TX_RATE_SGI) {
7770 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7772 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7773 }
7774 }
7775
7776 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7777 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7778
7779 if (NULL == reply_skb) {
7780 hddLog(VOS_TRACE_LEVEL_ERROR,
7781 FL("getLinkProperties: skb alloc failed"));
7782 return -EINVAL;
7783 }
7784
7785 if (nla_put_u8(reply_skb,
7786 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7787 nss) ||
7788 nla_put_u8(reply_skb,
7789 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7790 final_rate_flags) ||
7791 nla_put_u32(reply_skb,
7792 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7793 freq)) {
7794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7795 kfree_skb(reply_skb);
7796 return -EINVAL;
7797 }
7798
7799 return cfg80211_vendor_cmd_reply(reply_skb);
7800}
7801
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307802#define BEACON_MISS_THRESH_2_4 \
7803 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7804#define BEACON_MISS_THRESH_5_0 \
7805 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307806#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7807#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7808#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7809#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307810#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7811 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307812
7813/**
7814 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7815 * vendor command
7816 *
7817 * @wiphy: wiphy device pointer
7818 * @wdev: wireless device pointer
7819 * @data: Vendor command data buffer
7820 * @data_len: Buffer length
7821 *
7822 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7823 *
7824 * Return: EOK or other error codes.
7825 */
7826
7827static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7828 struct wireless_dev *wdev,
7829 const void *data,
7830 int data_len)
7831{
7832 struct net_device *dev = wdev->netdev;
7833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7835 hdd_station_ctx_t *pHddStaCtx;
7836 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7837 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307838 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839 eHalStatus status;
7840 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841 uint8_t hb_thresh_val;
7842
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307843 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7844 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7845 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307846 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7847 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7848 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307849 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7850 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307851 };
7852
7853 ENTER();
7854
7855 if (VOS_FTM_MODE == hdd_get_conparam()) {
7856 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7857 return -EINVAL;
7858 }
7859
7860 ret_val = wlan_hdd_validate_context(pHddCtx);
7861 if (ret_val) {
7862 return ret_val;
7863 }
7864
7865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7866
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7868 hddLog(LOGE, FL("Invalid ATTR"));
7869 return -EINVAL;
7870 }
7871
7872 /* check the Wifi Capability */
7873 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7874 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7875 {
7876 hddLog(VOS_TRACE_LEVEL_ERROR,
7877 FL("WIFICONFIG not supported by Firmware"));
7878 return -EINVAL;
7879 }
7880
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307881 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7882 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7883 modifyRoamParamsReq.value =
7884 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7885
7886 if (eHAL_STATUS_SUCCESS !=
7887 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7890 ret_val = -EINVAL;
7891 }
7892 return ret_val;
7893 }
7894
7895 /* Moved this down in order to provide provision to set beacon
7896 * miss penalty count irrespective of connection state.
7897 */
7898 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7899 hddLog(LOGE, FL("Not in Connected state!"));
7900 return -ENOTSUPP;
7901 }
7902
7903 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307904
7905 if (!pReq) {
7906 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7907 "%s: Not able to allocate memory for tSetWifiConfigParams",
7908 __func__);
7909 return eHAL_STATUS_E_MALLOC_FAILED;
7910 }
7911
7912 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7913
7914 pReq->sessionId = pAdapter->sessionId;
7915 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7916
7917 if (tb[PARAM_MODULATED_DTIM]) {
7918 pReq->paramValue = nla_get_u32(
7919 tb[PARAM_MODULATED_DTIM]);
7920 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7921 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307922 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307923 hdd_set_pwrparams(pHddCtx);
7924 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7925 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7926
7927 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7928 iw_full_power_cbfn, pAdapter,
7929 eSME_FULL_PWR_NEEDED_BY_HDD);
7930 }
7931 else
7932 {
7933 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7934 }
7935 }
7936
7937 if (tb[PARAM_STATS_AVG_FACTOR]) {
7938 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7939 pReq->paramValue = nla_get_u16(
7940 tb[PARAM_STATS_AVG_FACTOR]);
7941 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7942 pReq->paramType, pReq->paramValue);
7943 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7944
7945 if (eHAL_STATUS_SUCCESS != status)
7946 {
7947 vos_mem_free(pReq);
7948 pReq = NULL;
7949 ret_val = -EPERM;
7950 return ret_val;
7951 }
7952 }
7953
7954
7955 if (tb[PARAM_GUARD_TIME]) {
7956 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7957 pReq->paramValue = nla_get_u32(
7958 tb[PARAM_GUARD_TIME]);
7959 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7960 pReq->paramType, pReq->paramValue);
7961 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7962
7963 if (eHAL_STATUS_SUCCESS != status)
7964 {
7965 vos_mem_free(pReq);
7966 pReq = NULL;
7967 ret_val = -EPERM;
7968 return ret_val;
7969 }
7970
7971 }
7972
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307973 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7974 hb_thresh_val = nla_get_u8(
7975 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7976
7977 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7978 hb_thresh_val);
7979 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7980 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7981 NULL, eANI_BOOLEAN_FALSE);
7982
7983 status = sme_update_hb_threshold(
7984 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7985 WNI_CFG_HEART_BEAT_THRESHOLD,
7986 hb_thresh_val, eCSR_BAND_24);
7987 if (eHAL_STATUS_SUCCESS != status) {
7988 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7989 vos_mem_free(pReq);
7990 pReq = NULL;
7991 return -EPERM;
7992 }
7993 }
7994
7995 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7996 hb_thresh_val = nla_get_u8(
7997 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7998
7999 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8000 hb_thresh_val);
8001 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8002 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8003 NULL, eANI_BOOLEAN_FALSE);
8004
8005 status = sme_update_hb_threshold(
8006 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD,
8008 hb_thresh_val, eCSR_BAND_5G);
8009 if (eHAL_STATUS_SUCCESS != status) {
8010 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8011 vos_mem_free(pReq);
8012 pReq = NULL;
8013 return -EPERM;
8014 }
8015 }
8016
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308017 EXIT();
8018 return ret_val;
8019}
8020
8021/**
8022 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8023 * vendor command
8024 *
8025 * @wiphy: wiphy device pointer
8026 * @wdev: wireless device pointer
8027 * @data: Vendor command data buffer
8028 * @data_len: Buffer length
8029 *
8030 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8031 *
8032 * Return: EOK or other error codes.
8033 */
8034static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8035 struct wireless_dev *wdev,
8036 const void *data,
8037 int data_len)
8038{
8039 int ret;
8040
8041 vos_ssr_protect(__func__);
8042 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8043 data, data_len);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308048
8049/*
8050 * define short names for the global vendor params
8051 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8052 */
8053#define STATS_SET_INVALID \
8054 QCA_ATTR_NUD_STATS_SET_INVALID
8055#define STATS_SET_START \
8056 QCA_ATTR_NUD_STATS_SET_START
8057#define STATS_GW_IPV4 \
8058 QCA_ATTR_NUD_STATS_GW_IPV4
8059#define STATS_SET_MAX \
8060 QCA_ATTR_NUD_STATS_SET_MAX
8061
8062const struct nla_policy
8063qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8064{
8065 [STATS_SET_START] = {.type = NLA_FLAG },
8066 [STATS_GW_IPV4] = {.type = NLA_U32 },
8067};
8068
8069/**
8070 * hdd_set_nud_stats_cb() - hdd callback api to get status
8071 * @data: pointer to adapter
8072 * @rsp: status
8073 *
8074 * Return: None
8075 */
8076static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8077{
8078
8079 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8080
8081 if (NULL == adapter)
8082 return;
8083
8084 if (VOS_STATUS_SUCCESS == rsp) {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8086 "%s success received STATS_SET_START", __func__);
8087 } else {
8088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8089 "%s STATS_SET_START Failed!!", __func__);
8090 }
8091 return;
8092}
8093
8094/**
8095 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8096 * @wiphy: pointer to wireless wiphy structure.
8097 * @wdev: pointer to wireless_dev structure.
8098 * @data: pointer to apfind configuration data.
8099 * @data_len: the length in byte of apfind data.
8100 *
8101 * This is called when wlan driver needs to send arp stats to
8102 * firmware.
8103 *
8104 * Return: An error code or 0 on success.
8105 */
8106static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8107 struct wireless_dev *wdev,
8108 const void *data, int data_len)
8109{
8110 struct nlattr *tb[STATS_SET_MAX + 1];
8111 struct net_device *dev = wdev->netdev;
8112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308115 setArpStatsParams arp_stats_params;
8116 int err = 0;
8117
8118 ENTER();
8119
8120 err = wlan_hdd_validate_context(hdd_ctx);
8121 if (0 != err)
8122 return err;
8123
8124 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8127 return -EINVAL;
8128 }
8129
8130 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8131 qca_wlan_vendor_set_nud_stats);
8132 if (err)
8133 {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s STATS_SET_START ATTR", __func__);
8136 return err;
8137 }
8138
8139 if (tb[STATS_SET_START])
8140 {
8141 if (!tb[STATS_GW_IPV4]) {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s STATS_SET_START CMD", __func__);
8144 return -EINVAL;
8145 }
8146 arp_stats_params.flag = true;
8147 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8148 } else {
8149 arp_stats_params.flag = false;
8150 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8153 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308154 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8155 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308156
8157 arp_stats_params.pkt_type = 1; // ARP packet type
8158
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308159 if (arp_stats_params.flag) {
8160 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8161 WLANTL_SetARPFWDatapath(pVosContext, true);
8162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8163 "%s Set FW in data path for ARP with tgt IP :%d",
8164 __func__, hdd_ctx->track_arp_ip);
8165 }
8166 else {
8167 WLANTL_SetARPFWDatapath(pVosContext, false);
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8169 "%s Remove FW from data path", __func__);
8170 }
8171
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308172 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8173 arp_stats_params.data_ctx = adapter;
8174
8175 if (eHAL_STATUS_SUCCESS !=
8176 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8178 "%s STATS_SET_START CMD Failed!!", __func__);
8179 return -EINVAL;
8180 }
8181
8182 EXIT();
8183
8184 return err;
8185}
8186
8187/**
8188 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8189 * @wiphy: pointer to wireless wiphy structure.
8190 * @wdev: pointer to wireless_dev structure.
8191 * @data: pointer to apfind configuration data.
8192 * @data_len: the length in byte of apfind data.
8193 *
8194 * This is called when wlan driver needs to send arp stats to
8195 * firmware.
8196 *
8197 * Return: An error code or 0 on success.
8198 */
8199static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8200 struct wireless_dev *wdev,
8201 const void *data, int data_len)
8202{
8203 int ret;
8204
8205 vos_ssr_protect(__func__);
8206 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8207 vos_ssr_unprotect(__func__);
8208
8209 return ret;
8210}
8211#undef STATS_SET_INVALID
8212#undef STATS_SET_START
8213#undef STATS_GW_IPV4
8214#undef STATS_SET_MAX
8215
8216/*
8217 * define short names for the global vendor params
8218 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8219 */
8220#define STATS_GET_INVALID \
8221 QCA_ATTR_NUD_STATS_SET_INVALID
8222#define COUNT_FROM_NETDEV \
8223 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8224#define COUNT_TO_LOWER_MAC \
8225 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8226#define RX_COUNT_BY_LOWER_MAC \
8227 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8228#define COUNT_TX_SUCCESS \
8229 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8230#define RSP_RX_COUNT_BY_LOWER_MAC \
8231 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8232#define RSP_RX_COUNT_BY_UPPER_MAC \
8233 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8234#define RSP_COUNT_TO_NETDEV \
8235 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8236#define RSP_COUNT_OUT_OF_ORDER_DROP \
8237 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8238#define AP_LINK_ACTIVE \
8239 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8240#define AP_LINK_DAD \
8241 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8242#define STATS_GET_MAX \
8243 QCA_ATTR_NUD_STATS_GET_MAX
8244
8245const struct nla_policy
8246qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8247{
8248 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8249 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8250 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8251 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8252 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8253 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8254 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8255 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8256 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8257 [AP_LINK_DAD] = {.type = NLA_FLAG },
8258};
8259
8260static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8261{
8262
8263 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308264 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308265 struct hdd_nud_stats_context *context;
8266 int status;
8267
8268 ENTER();
8269
8270 if (NULL == adapter)
8271 return;
8272
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308273 if (!rsp) {
8274 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308275 return;
8276 }
8277
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308278 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8279 status = wlan_hdd_validate_context(hdd_ctx);
8280 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308281 return;
8282 }
8283
8284 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8285 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8286 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8287 adapter->dad |= rsp->dad;
8288
8289 spin_lock(&hdd_context_lock);
8290 context = &hdd_ctx->nud_stats_context;
8291 complete(&context->response_event);
8292 spin_unlock(&hdd_context_lock);
8293
8294 return;
8295}
8296static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8297 struct wireless_dev *wdev,
8298 const void *data, int data_len)
8299{
8300 int err = 0;
8301 unsigned long rc;
8302 struct hdd_nud_stats_context *context;
8303 struct net_device *dev = wdev->netdev;
8304 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8305 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8306 getArpStatsParams arp_stats_params;
8307 struct sk_buff *skb;
8308
8309 ENTER();
8310
8311 err = wlan_hdd_validate_context(hdd_ctx);
8312 if (0 != err)
8313 return err;
8314
8315 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8316 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8317 arp_stats_params.data_ctx = adapter;
8318
8319 spin_lock(&hdd_context_lock);
8320 context = &hdd_ctx->nud_stats_context;
8321 INIT_COMPLETION(context->response_event);
8322 spin_unlock(&hdd_context_lock);
8323
8324 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8327 return -EINVAL;
8328 }
8329
8330 if (eHAL_STATUS_SUCCESS !=
8331 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8333 "%s STATS_SET_START CMD Failed!!", __func__);
8334 return -EINVAL;
8335 }
8336
8337 rc = wait_for_completion_timeout(&context->response_event,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8339 if (!rc)
8340 {
8341 hddLog(LOGE,
8342 FL("Target response timed out request "));
8343 return -ETIMEDOUT;
8344 }
8345
8346 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8347 WLAN_NUD_STATS_LEN);
8348 if (!skb)
8349 {
8350 hddLog(VOS_TRACE_LEVEL_ERROR,
8351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8352 __func__);
8353 return -ENOMEM;
8354 }
8355
8356 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8357 adapter->hdd_stats.hddArpStats.txCount) ||
8358 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8359 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8360 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8361 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8362 nla_put_u16(skb, COUNT_TX_SUCCESS,
8363 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8364 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8365 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8366 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8367 adapter->hdd_stats.hddArpStats.rxCount) ||
8368 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8369 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8370 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8371 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8372 hddLog(LOGE, FL("nla put fail"));
8373 kfree_skb(skb);
8374 return -EINVAL;
8375 }
8376 if (adapter->con_status)
8377 nla_put_flag(skb, AP_LINK_ACTIVE);
8378 if (adapter->dad)
8379 nla_put_flag(skb, AP_LINK_DAD);
8380
8381 cfg80211_vendor_cmd_reply(skb);
8382 return err;
8383}
8384
8385static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8386 struct wireless_dev *wdev,
8387 const void *data, int data_len)
8388{
8389 int ret;
8390
8391 vos_ssr_protect(__func__);
8392 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8393 vos_ssr_unprotect(__func__);
8394
8395 return ret;
8396}
8397
8398#undef QCA_ATTR_NUD_STATS_SET_INVALID
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8400#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8404#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8405#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8406#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8407#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8408#undef QCA_ATTR_NUD_STATS_GET_MAX
8409
8410
8411
Kapil Guptaee33bf12016-12-20 18:27:37 +05308412#ifdef WLAN_FEATURE_APFIND
8413/**
8414 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8415 * @wiphy: pointer to wireless wiphy structure.
8416 * @wdev: pointer to wireless_dev structure.
8417 * @data: pointer to apfind configuration data.
8418 * @data_len: the length in byte of apfind data.
8419 *
8420 * This is called when wlan driver needs to send APFIND configurations to
8421 * firmware.
8422 *
8423 * Return: An error code or 0 on success.
8424 */
8425static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8426 struct wireless_dev *wdev,
8427 const void *data, int data_len)
8428{
8429 struct sme_ap_find_request_req apfind_req;
8430 VOS_STATUS status;
8431 int ret_val;
8432 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8433
8434 ENTER();
8435
8436 ret_val = wlan_hdd_validate_context(hdd_ctx);
8437 if (ret_val)
8438 return ret_val;
8439
8440 if (VOS_FTM_MODE == hdd_get_conparam()) {
8441 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8442 return -EPERM;
8443 }
8444
8445 apfind_req.request_data_len = data_len;
8446 apfind_req.request_data = data;
8447
8448 status = sme_apfind_set_cmd(&apfind_req);
8449 if (VOS_STATUS_SUCCESS != status) {
8450 ret_val = -EIO;
8451 }
8452 return ret_val;
8453}
8454
8455/**
8456 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8457 * @wiphy: pointer to wireless wiphy structure.
8458 * @wdev: pointer to wireless_dev structure.
8459 * @data: pointer to apfind configuration data.
8460 * @data_len: the length in byte of apfind data.
8461 *
8462 * This is called when wlan driver needs to send APFIND configurations to
8463 * firmware.
8464 *
8465 * Return: An error code or 0 on success.
8466 */
8467static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8468 struct wireless_dev *wdev,
8469 const void *data, int data_len)
8470{
8471 int ret;
8472
8473 vos_ssr_protect(__func__);
8474 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8475 vos_ssr_unprotect(__func__);
8476
8477 return ret;
8478}
8479#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308480const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8481{
Mukul Sharma2a271632014-10-13 14:59:01 +05308482 {
8483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8486 WIPHY_VENDOR_CMD_NEED_NETDEV |
8487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308488 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308489 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308490
8491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV |
8496 WIPHY_VENDOR_CMD_NEED_RUNNING,
8497 .doit = wlan_hdd_cfg80211_nan_request
8498 },
8499
Sunil Duttc69bccb2014-05-26 21:30:20 +05308500#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8501 {
8502 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8503 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8504 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8505 WIPHY_VENDOR_CMD_NEED_NETDEV |
8506 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308507 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308508 },
8509
8510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
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_set
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_GET,
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_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308526 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308527#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308528#ifdef WLAN_FEATURE_EXTSCAN
8529 {
8530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8533 WIPHY_VENDOR_CMD_NEED_NETDEV |
8534 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308535 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308536 },
8537 {
8538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8541 WIPHY_VENDOR_CMD_NEED_NETDEV |
8542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308543 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308544 },
8545 {
8546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8549 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308550 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308551 },
8552 {
8553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8556 WIPHY_VENDOR_CMD_NEED_NETDEV |
8557 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308558 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308559 },
8560 {
8561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8564 WIPHY_VENDOR_CMD_NEED_NETDEV |
8565 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308566 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308567 },
8568 {
8569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8572 WIPHY_VENDOR_CMD_NEED_NETDEV |
8573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308574 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308575 },
8576 {
8577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8580 WIPHY_VENDOR_CMD_NEED_NETDEV |
8581 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308582 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308583 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308585/*EXT TDLS*/
8586 {
8587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8590 WIPHY_VENDOR_CMD_NEED_NETDEV |
8591 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308592 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308593 },
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308601 },
8602 {
8603 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8604 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8605 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8606 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308607 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308608 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308614 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308615 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308621 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308622 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308623 {
8624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8627 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308628 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308629 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308636 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308637 {
8638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8641 WIPHY_VENDOR_CMD_NEED_NETDEV |
8642 WIPHY_VENDOR_CMD_NEED_RUNNING,
8643 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8644 },
8645 {
8646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8649 WIPHY_VENDOR_CMD_NEED_NETDEV |
8650 WIPHY_VENDOR_CMD_NEED_RUNNING,
8651 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308652 },
8653 {
8654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8657 WIPHY_VENDOR_CMD_NEED_NETDEV,
8658 .doit = wlan_hdd_cfg80211_wifi_logger_start
8659 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV|
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
8666 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308667 },
8668 {
8669 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8670 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8671 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8672 WIPHY_VENDOR_CMD_NEED_NETDEV |
8673 WIPHY_VENDOR_CMD_NEED_RUNNING,
8674 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308675 },
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
8682 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308683 },
8684#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
8691 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308692 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308693#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308694 {
8695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8698 WIPHY_VENDOR_CMD_NEED_NETDEV |
8699 WIPHY_VENDOR_CMD_NEED_RUNNING,
8700 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308701 },
8702 {
8703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8706 WIPHY_VENDOR_CMD_NEED_NETDEV |
8707 WIPHY_VENDOR_CMD_NEED_RUNNING,
8708 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308709 },
8710#ifdef WLAN_FEATURE_APFIND
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV,
8716 .doit = wlan_hdd_cfg80211_apfind_cmd
8717 },
8718#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV |
8724 WIPHY_VENDOR_CMD_NEED_RUNNING,
8725 .doit = wlan_hdd_cfg80211_set_nud_stats
8726 },
8727 {
8728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8731 WIPHY_VENDOR_CMD_NEED_NETDEV |
8732 WIPHY_VENDOR_CMD_NEED_RUNNING,
8733 .doit = wlan_hdd_cfg80211_get_nud_stats
8734 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308735 {
8736 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8737 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8738 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8739 WIPHY_VENDOR_CMD_NEED_NETDEV |
8740 WIPHY_VENDOR_CMD_NEED_RUNNING,
8741 .doit = hdd_cfg80211_get_station_cmd
8742 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308743};
8744
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008745/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308746static const
8747struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008748{
8749#ifdef FEATURE_WLAN_CH_AVOID
8750 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308751 .vendor_id = QCA_NL80211_VENDOR_ID,
8752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008753 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308754#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8755#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8756 {
8757 /* Index = 1*/
8758 .vendor_id = QCA_NL80211_VENDOR_ID,
8759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8760 },
8761 {
8762 /* Index = 2*/
8763 .vendor_id = QCA_NL80211_VENDOR_ID,
8764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8765 },
8766 {
8767 /* Index = 3*/
8768 .vendor_id = QCA_NL80211_VENDOR_ID,
8769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8770 },
8771 {
8772 /* Index = 4*/
8773 .vendor_id = QCA_NL80211_VENDOR_ID,
8774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8775 },
8776 {
8777 /* Index = 5*/
8778 .vendor_id = QCA_NL80211_VENDOR_ID,
8779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8780 },
8781 {
8782 /* Index = 6*/
8783 .vendor_id = QCA_NL80211_VENDOR_ID,
8784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8785 },
8786#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308787#ifdef WLAN_FEATURE_EXTSCAN
8788 {
8789 .vendor_id = QCA_NL80211_VENDOR_ID,
8790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8791 },
8792 {
8793 .vendor_id = QCA_NL80211_VENDOR_ID,
8794 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8795 },
8796 {
8797 .vendor_id = QCA_NL80211_VENDOR_ID,
8798 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8799 },
8800 {
8801 .vendor_id = QCA_NL80211_VENDOR_ID,
8802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8803 },
8804 {
8805 .vendor_id = QCA_NL80211_VENDOR_ID,
8806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8807 },
8808 {
8809 .vendor_id = QCA_NL80211_VENDOR_ID,
8810 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8811 },
8812 {
8813 .vendor_id = QCA_NL80211_VENDOR_ID,
8814 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8815 },
8816 {
8817 .vendor_id = QCA_NL80211_VENDOR_ID,
8818 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8819 },
8820 {
8821 .vendor_id = QCA_NL80211_VENDOR_ID,
8822 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8823 },
8824 {
8825 .vendor_id = QCA_NL80211_VENDOR_ID,
8826 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8827 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308828#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308829/*EXT TDLS*/
8830 {
8831 .vendor_id = QCA_NL80211_VENDOR_ID,
8832 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8833 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308834 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8835 .vendor_id = QCA_NL80211_VENDOR_ID,
8836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8837 },
8838
Srinivas Dasari030bad32015-02-18 23:23:54 +05308839
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308840 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308841 .vendor_id = QCA_NL80211_VENDOR_ID,
8842 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8843 },
8844
Sushant Kaushik084f6592015-09-10 13:11:56 +05308845 {
8846 .vendor_id = QCA_NL80211_VENDOR_ID,
8847 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308848 },
8849 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8850 .vendor_id = QCA_NL80211_VENDOR_ID,
8851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8852 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308853 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8856 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308857 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8858 .vendor_id = QCA_NL80211_VENDOR_ID,
8859 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8860 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308861 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8862 .vendor_id = QCA_NL80211_VENDOR_ID,
8863 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8864 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308865 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8866 .vendor_id = QCA_NL80211_VENDOR_ID,
8867 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8868 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008869};
8870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308872 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 * This function is called by hdd_wlan_startup()
8874 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308875 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308877struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008878{
8879 struct wiphy *wiphy;
8880 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 /*
8882 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 */
8884 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8885
8886 if (!wiphy)
8887 {
8888 /* Print error and jump into err label and free the memory */
8889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8890 return NULL;
8891 }
8892
Sunil Duttc69bccb2014-05-26 21:30:20 +05308893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 return wiphy;
8895}
8896
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308897#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8898 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8899/**
8900 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8901 * @wiphy: pointer to wiphy
8902 * @config: pointer to config
8903 *
8904 * Return: None
8905 */
8906static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8907 hdd_config_t *config)
8908{
8909 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8910 if (config->max_sched_scan_plan_interval)
8911 wiphy->max_sched_scan_plan_interval =
8912 config->max_sched_scan_plan_interval;
8913 if (config->max_sched_scan_plan_iterations)
8914 wiphy->max_sched_scan_plan_iterations =
8915 config->max_sched_scan_plan_iterations;
8916}
8917#else
8918static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8919 hdd_config_t *config)
8920{
8921}
8922#endif
8923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924/*
8925 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 * private ioctl to change the band value
8928 */
8929int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8930{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308931 int i, j;
8932 eNVChannelEnabledType channelEnabledState;
8933
Jeff Johnsone7245742012-09-05 17:12:55 -07008934 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308935
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308936 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308938
8939 if (NULL == wiphy->bands[i])
8940 {
8941 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8942 __func__, i);
8943 continue;
8944 }
8945
8946 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8947 {
8948 struct ieee80211_supported_band *band = wiphy->bands[i];
8949
8950 channelEnabledState = vos_nv_getChannelEnabledState(
8951 band->channels[j].hw_value);
8952
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308953 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308954 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308955 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308956 continue;
8957 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308958 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308959 {
8960 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8961 continue;
8962 }
8963
8964 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8965 NV_CHANNEL_INVALID == channelEnabledState)
8966 {
8967 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8968 }
8969 else if (NV_CHANNEL_DFS == channelEnabledState)
8970 {
8971 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8972 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8973 }
8974 else
8975 {
8976 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8977 |IEEE80211_CHAN_RADAR);
8978 }
8979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 }
8981 return 0;
8982}
8983/*
8984 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308985 * This function is called by hdd_wlan_startup()
8986 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 * This function is used to initialize and register wiphy structure.
8988 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308989int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 struct wiphy *wiphy,
8991 hdd_config_t *pCfg
8992 )
8993{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308994 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308995 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8996
Jeff Johnsone7245742012-09-05 17:12:55 -07008997 ENTER();
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 /* Now bind the underlying wlan device with wiphy */
9000 set_wiphy_dev(wiphy, dev);
9001
9002 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009003
Kiet Lam6c583332013-10-14 05:37:09 +05309004#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009005 /* the flag for the other case would be initialzed in
9006 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9008 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9009#else
Amar Singhal0a402232013-10-11 20:57:16 -07009010 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309011#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309012#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009013
Amar Singhalfddc28c2013-09-05 13:03:40 -07009014 /* This will disable updating of NL channels from passive to
9015 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9017 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9018#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009019 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309020#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009021
Amar Singhala49cbc52013-10-08 18:37:44 -07009022
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009024 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9025 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9026 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009027 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309029 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309030#else
9031 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9032#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009033#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009034
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009035#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009036 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009037#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009038 || pCfg->isFastRoamIniFeatureEnabled
9039#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009040#ifdef FEATURE_WLAN_ESE
9041 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009042#endif
9043 )
9044 {
9045 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9046 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009047#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009048#ifdef FEATURE_WLAN_TDLS
9049 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9050 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9051#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309052#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309053 if (pCfg->configPNOScanSupport)
9054 {
9055 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9056 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9057 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9058 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9059 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309060#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009061
Abhishek Singh10d85972015-04-17 10:27:23 +05309062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9063 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9064#endif
9065
Amar Singhalfddc28c2013-09-05 13:03:40 -07009066#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009067 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9068 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009069 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009070 driver need to determine what to do with both
9071 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009072
9073 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009074#else
9075 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009076#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009077
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309078 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9079
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309080 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309082 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9083
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309085 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9086 | BIT(NL80211_IFTYPE_ADHOC)
9087 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9088 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309089 | BIT(NL80211_IFTYPE_AP)
9090 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309092 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009093 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9095 if( pCfg->enableMCC )
9096 {
9097 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309098 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009099
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309100 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309101 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009102
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309103 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309104 wiphy->iface_combinations = wlan_hdd_iface_combination;
9105 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009106#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309107 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 /* Before registering we need to update the ht capabilitied based
9110 * on ini values*/
9111 if( !pCfg->ShortGI20MhzEnable )
9112 {
9113 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9114 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 }
9116
9117 if( !pCfg->ShortGI40MhzEnable )
9118 {
9119 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9120 }
9121
9122 if( !pCfg->nChannelBondingMode5GHz )
9123 {
9124 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9125 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309126 /*
9127 * In case of static linked driver at the time of driver unload,
9128 * module exit doesn't happens. Module cleanup helps in cleaning
9129 * of static memory.
9130 * If driver load happens statically, at the time of driver unload,
9131 * wiphy flags don't get reset because of static memory.
9132 * It's better not to store channel in static memory.
9133 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309134 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9135 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309136 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309137 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309138 {
9139 hddLog(VOS_TRACE_LEVEL_ERROR,
9140 FL("Not enough memory to allocate channels"));
9141 return -ENOMEM;
9142 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309143 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309144 &hdd_channels_2_4_GHZ[0],
9145 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009146
Agrawal Ashish97dec502015-11-26 20:20:58 +05309147 if (true == hdd_is_5g_supported(pHddCtx))
9148 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309149 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9150 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309151 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309152 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309153 {
9154 hddLog(VOS_TRACE_LEVEL_ERROR,
9155 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309156 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9157 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309158 return -ENOMEM;
9159 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309160 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309161 &hdd_channels_5_GHZ[0],
9162 sizeof(hdd_channels_5_GHZ));
9163 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309164
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309165 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309166 {
9167
9168 if (NULL == wiphy->bands[i])
9169 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309170 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309171 __func__, i);
9172 continue;
9173 }
9174
9175 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9176 {
9177 struct ieee80211_supported_band *band = wiphy->bands[i];
9178
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309179 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309180 {
9181 // Enable social channels for P2P
9182 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9183 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9184 else
9185 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9186 continue;
9187 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309188 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309189 {
9190 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9191 continue;
9192 }
9193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 }
9195 /*Initialise the supported cipher suite details*/
9196 wiphy->cipher_suites = hdd_cipher_suites;
9197 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9198
9199 /*signal strength in mBm (100*dBm) */
9200 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9201
9202#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309203 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
Sunil Duttc69bccb2014-05-26 21:30:20 +05309206 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9207 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009208 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9209 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9210
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309211 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9212
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309213 EXIT();
9214 return 0;
9215}
9216
9217/* In this function we are registering wiphy. */
9218int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9219{
9220 ENTER();
9221 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 if (0 > wiphy_register(wiphy))
9223 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309224 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9226 return -EIO;
9227 }
9228
9229 EXIT();
9230 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309231}
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309233/* In this function we are updating channel list when,
9234 regulatory domain is FCC and country code is US.
9235 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9236 As per FCC smart phone is not a indoor device.
9237 GO should not opeate on indoor channels */
9238void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9239{
9240 int j;
9241 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9242 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9243 //Default counrtycode from NV at the time of wiphy initialization.
9244 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9245 &defaultCountryCode[0]))
9246 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009247 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309248 }
9249 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9250 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309251 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309252 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309253 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309254 return;
9255 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309256 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309257 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309258 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309259 // Mark UNII -1 band channel as passive
9260 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9261 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9262 }
9263 }
9264}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309265/* This function registers for all frame which supplicant is interested in */
9266void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009267{
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9269 /* Register for all P2P action, public action etc frames */
9270 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009271 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309272 /* Register frame indication call back */
9273 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 /* Right now we are registering these frame when driver is getting
9275 initialized. Once we will move to 2.6.37 kernel, in which we have
9276 frame register ops, we will move this code as a part of that */
9277 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9280
9281 /* GAS Initial Response */
9282 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9283 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 /* GAS Comeback Request */
9286 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9287 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9288
9289 /* GAS Comeback Response */
9290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9291 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9292
9293 /* P2P Public Action */
9294 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 P2P_PUBLIC_ACTION_FRAME_SIZE );
9297
9298 /* P2P Action */
9299 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9300 (v_U8_t*)P2P_ACTION_FRAME,
9301 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009302
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309303 /* WNM BSS Transition Request frame */
9304 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9305 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9306 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009307
9308 /* WNM-Notification */
9309 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9310 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9311 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009312}
9313
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309314void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009315{
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9317 /* Register for all P2P action, public action etc frames */
9318 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9319
Jeff Johnsone7245742012-09-05 17:12:55 -07009320 ENTER();
9321
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 /* Right now we are registering these frame when driver is getting
9323 initialized. Once we will move to 2.6.37 kernel, in which we have
9324 frame register ops, we will move this code as a part of that */
9325 /* GAS Initial Request */
9326
9327 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9328 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9329
9330 /* GAS Initial Response */
9331 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9332 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 /* GAS Comeback Request */
9335 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9336 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9337
9338 /* GAS Comeback Response */
9339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9340 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9341
9342 /* P2P Public Action */
9343 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 P2P_PUBLIC_ACTION_FRAME_SIZE );
9346
9347 /* P2P Action */
9348 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9349 (v_U8_t*)P2P_ACTION_FRAME,
9350 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009351 /* WNM-Notification */
9352 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9353 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9354 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009355}
9356
9357#ifdef FEATURE_WLAN_WAPI
9358void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309359 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009360{
9361 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9362 tCsrRoamSetKey setKey;
9363 v_BOOL_t isConnected = TRUE;
9364 int status = 0;
9365 v_U32_t roamId= 0xFF;
9366 tANI_U8 *pKeyPtr = NULL;
9367 int n = 0;
9368
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9370 __func__, hdd_device_modetoString(pAdapter->device_mode),
9371 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309373 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 setKey.keyId = key_index; // Store Key ID
9375 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9376 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9377 setKey.paeRole = 0 ; // the PAE role
9378 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9379 {
9380 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9381 }
9382 else
9383 {
9384 isConnected = hdd_connIsConnected(pHddStaCtx);
9385 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9386 }
9387 setKey.keyLength = key_Len;
9388 pKeyPtr = setKey.Key;
9389 memcpy( pKeyPtr, key, key_Len);
9390
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 __func__, key_Len);
9393 for (n = 0 ; n < key_Len; n++)
9394 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9395 __func__,n,setKey.Key[n]);
9396
9397 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9398 if ( isConnected )
9399 {
9400 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9401 pAdapter->sessionId, &setKey, &roamId );
9402 }
9403 if ( status != 0 )
9404 {
9405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9406 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9407 __LINE__, status );
9408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9409 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309410 /* Need to clear any trace of key value in the memory.
9411 * Thus zero out the memory even though it is local
9412 * variable.
9413 */
9414 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009415}
9416#endif /* FEATURE_WLAN_WAPI*/
9417
9418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 beacon_data_t **ppBeacon,
9421 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009422#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009424 beacon_data_t **ppBeacon,
9425 struct cfg80211_beacon_data *params,
9426 int dtim_period)
9427#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428{
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 int size;
9430 beacon_data_t *beacon = NULL;
9431 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309432 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9433 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009434
Jeff Johnsone7245742012-09-05 17:12:55 -07009435 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309437 {
9438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009442
9443 old = pAdapter->sessionCtx.ap.beacon;
9444
9445 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309446 {
9447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9448 FL("session(%d) old and new heads points to NULL"),
9449 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309451 }
9452
9453 if (params->tail && !params->tail_len)
9454 {
9455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9456 FL("tail_len is zero but tail is not NULL"));
9457 return -EINVAL;
9458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
Jeff Johnson295189b2012-06-20 16:38:30 -07009460#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9461 /* Kernel 3.0 is not updating dtim_period for set beacon */
9462 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9465 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009468#endif
9469
Kapil Gupta137ef892016-12-13 19:38:00 +05309470 if (params->head)
9471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309473 head = params->head;
9474 } else
9475 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309477 head = old->head;
9478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
Kapil Gupta137ef892016-12-13 19:38:00 +05309480 if (params->tail || !old)
9481 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309483 tail = params->tail;
9484 } else
9485 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309487 tail = old->tail;
9488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009489
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 if (params->proberesp_ies || !old)
9491 {
9492 proberesp_ies_len = params->proberesp_ies_len;
9493 proberesp_ies = params->proberesp_ies;
9494 } else
9495 {
9496 proberesp_ies_len = old->proberesp_ies_len;
9497 proberesp_ies = old->proberesp_ies;
9498 }
9499
9500 if (params->assocresp_ies || !old)
9501 {
9502 assocresp_ies_len = params->assocresp_ies_len;
9503 assocresp_ies = params->assocresp_ies;
9504 } else
9505 {
9506 assocresp_ies_len = old->assocresp_ies_len;
9507 assocresp_ies = old->assocresp_ies;
9508 }
9509
9510 size = sizeof(beacon_data_t) + head_len + tail_len +
9511 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009512
9513 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309515 {
9516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9517 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009520
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009521#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309522 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 beacon->dtim_period = params->dtim_period;
9524 else
9525 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009526#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309527 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009528 beacon->dtim_period = dtim_period;
9529 else
9530 beacon->dtim_period = old->dtim_period;
9531#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309532
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9534 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309535 beacon->proberesp_ies = beacon->tail + tail_len;
9536 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9537
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 beacon->head_len = head_len;
9539 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309540 beacon->proberesp_ies_len = proberesp_ies_len;
9541 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
c_manjee527ecac2017-01-25 12:25:27 +05309543 if (head && head_len)
9544 memcpy(beacon->head, head, head_len);
9545 if (tail && tail_len)
9546 memcpy(beacon->tail, tail, tail_len);
9547 if (proberesp_ies && proberesp_ies_len)
9548 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9549 if (assocresp_ies && assocresp_ies_len)
9550 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009551
9552 *ppBeacon = beacon;
9553
9554 kfree(old);
9555
9556 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009557}
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309559v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9561 const v_U8_t *pIes,
9562#else
9563 v_U8_t *pIes,
9564#endif
9565 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009566{
9567 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309568 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 elem_id = ptr[0];
9574 elem_len = ptr[1];
9575 left -= 2;
9576 if(elem_len > left)
9577 {
9578 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009579 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 eid,elem_len,left);
9581 return NULL;
9582 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 {
9585 return ptr;
9586 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 left -= elem_len;
9589 ptr += (elem_len + 2);
9590 }
9591 return NULL;
9592}
9593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594/* Check if rate is 11g rate or not */
9595static int wlan_hdd_rate_is_11g(u8 rate)
9596{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009597 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 u8 i;
9599 for (i = 0; i < 8; i++)
9600 {
9601 if(rate == gRateArray[i])
9602 return TRUE;
9603 }
9604 return FALSE;
9605}
9606
9607/* Check for 11g rate and set proper 11g only mode */
9608static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9609 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9610{
9611 u8 i, num_rates = pIe[0];
9612
9613 pIe += 1;
9614 for ( i = 0; i < num_rates; i++)
9615 {
9616 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9617 {
9618 /* If rate set have 11g rate than change the mode to 11G */
9619 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9620 if (pIe[i] & BASIC_RATE_MASK)
9621 {
9622 /* If we have 11g rate as basic rate, it means mode
9623 is 11g only mode.
9624 */
9625 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9626 *pCheckRatesfor11g = FALSE;
9627 }
9628 }
9629 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9630 {
9631 *require_ht = TRUE;
9632 }
9633 }
9634 return;
9635}
9636
9637static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9638{
9639 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9640 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9641 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9642 u8 checkRatesfor11g = TRUE;
9643 u8 require_ht = FALSE;
9644 u8 *pIe=NULL;
9645
9646 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9647
9648 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9649 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9650 if (pIe != NULL)
9651 {
9652 pIe += 1;
9653 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9654 &pConfig->SapHw_mode);
9655 }
9656
9657 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9658 WLAN_EID_EXT_SUPP_RATES);
9659 if (pIe != NULL)
9660 {
9661
9662 pIe += 1;
9663 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9664 &pConfig->SapHw_mode);
9665 }
9666
9667 if( pConfig->channel > 14 )
9668 {
9669 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9670 }
9671
9672 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9673 WLAN_EID_HT_CAPABILITY);
9674
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309675 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 {
9677 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9678 if(require_ht)
9679 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9680 }
9681}
9682
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9684 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9685{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009686 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309687 v_U8_t *pIe = NULL;
9688 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9689
9690 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9691 pBeacon->tail, pBeacon->tail_len);
9692
9693 if (pIe)
9694 {
9695 ielen = pIe[1] + 2;
9696 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9697 {
9698 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9699 }
9700 else
9701 {
9702 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9703 return -EINVAL;
9704 }
9705 *total_ielen += ielen;
9706 }
9707 return 0;
9708}
9709
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009710static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9711 v_U8_t *genie, v_U8_t *total_ielen)
9712{
9713 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9714 int left = pBeacon->tail_len;
9715 v_U8_t *ptr = pBeacon->tail;
9716 v_U8_t elem_id, elem_len;
9717 v_U16_t ielen = 0;
9718
9719 if ( NULL == ptr || 0 == left )
9720 return;
9721
9722 while (left >= 2)
9723 {
9724 elem_id = ptr[0];
9725 elem_len = ptr[1];
9726 left -= 2;
9727 if (elem_len > left)
9728 {
9729 hddLog( VOS_TRACE_LEVEL_ERROR,
9730 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9731 elem_id, elem_len, left);
9732 return;
9733 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309734 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009735 {
9736 /* skipping the VSIE's which we don't want to include or
9737 * it will be included by existing code
9738 */
9739 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9740#ifdef WLAN_FEATURE_WFD
9741 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9742#endif
9743 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9744 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9745 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9746 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9747 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9748 {
9749 ielen = ptr[1] + 2;
9750 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9751 {
9752 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9753 *total_ielen += ielen;
9754 }
9755 else
9756 {
9757 hddLog( VOS_TRACE_LEVEL_ERROR,
9758 "IE Length is too big "
9759 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9760 elem_id, elem_len, *total_ielen);
9761 }
9762 }
9763 }
9764
9765 left -= elem_len;
9766 ptr += (elem_len + 2);
9767 }
9768 return;
9769}
9770
Kapil Gupta137ef892016-12-13 19:38:00 +05309771int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009772{
9773 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309774 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009776 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309777 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778
9779 genie = vos_mem_malloc(MAX_GENIE_LEN);
9780
9781 if(genie == NULL) {
9782
9783 return -ENOMEM;
9784 }
9785
Kapil Gupta137ef892016-12-13 19:38:00 +05309786 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309787 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9788 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309790 hddLog(LOGE,
9791 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309792 ret = -EINVAL;
9793 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 }
9795
9796#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309797 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9798 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9799 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309800 hddLog(LOGE,
9801 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309802 ret = -EINVAL;
9803 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 }
9805#endif
9806
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309807 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9808 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309810 hddLog(LOGE,
9811 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309812 ret = -EINVAL;
9813 goto done;
9814 }
9815
9816 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9817 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009818 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9822 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9823 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9824 {
9825 hddLog(LOGE,
9826 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 ret = -EINVAL;
9828 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 }
9830
9831 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9832 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9833 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9834 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9835 ==eHAL_STATUS_FAILURE)
9836 {
9837 hddLog(LOGE,
9838 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009839 ret = -EINVAL;
9840 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 }
9842
9843 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309844 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309846 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 u8 probe_rsp_ie_len[3] = {0};
9848 u8 counter = 0;
9849 /* Check Probe Resp Length if it is greater then 255 then Store
9850 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9851 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9852 Store More then 255 bytes into One Variable.
9853 */
9854 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9855 {
9856 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9857 {
9858 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9859 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9860 }
9861 else
9862 {
9863 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9864 rem_probe_resp_ie_len = 0;
9865 }
9866 }
9867
9868 rem_probe_resp_ie_len = 0;
9869
9870 if (probe_rsp_ie_len[0] > 0)
9871 {
9872 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9873 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309874 (tANI_U8*)&pBeacon->
9875 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 probe_rsp_ie_len[0], NULL,
9877 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9878 {
9879 hddLog(LOGE,
9880 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009881 ret = -EINVAL;
9882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 }
9884 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9885 }
9886
9887 if (probe_rsp_ie_len[1] > 0)
9888 {
9889 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9890 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
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[1], NULL,
9894 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9895 {
9896 hddLog(LOGE,
9897 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 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[1];
9902 }
9903
9904 if (probe_rsp_ie_len[2] > 0)
9905 {
9906 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9907 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
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[2], NULL,
9911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9912 {
9913 hddLog(LOGE,
9914 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 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[2];
9919 }
9920
9921 if (probe_rsp_ie_len[1] == 0 )
9922 {
9923 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9924 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9925 eANI_BOOLEAN_FALSE) )
9926 {
9927 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009928 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 }
9930 }
9931
9932 if (probe_rsp_ie_len[2] == 0 )
9933 {
9934 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9935 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9936 eANI_BOOLEAN_FALSE) )
9937 {
9938 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009939 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941 }
9942
9943 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9944 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9945 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9946 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9947 == eHAL_STATUS_FAILURE)
9948 {
9949 hddLog(LOGE,
9950 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009951 ret = -EINVAL;
9952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 }
9954 }
9955 else
9956 {
9957 // Reset WNI_CFG_PROBE_RSP Flags
9958 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9959
9960 hddLog(VOS_TRACE_LEVEL_INFO,
9961 "%s: No Probe Response IE received in set beacon",
9962 __func__);
9963 }
9964
9965 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309966 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 {
9968 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309969 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9970 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9972 {
9973 hddLog(LOGE,
9974 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009975 ret = -EINVAL;
9976 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 }
9978
9979 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9980 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9981 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9982 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9983 == eHAL_STATUS_FAILURE)
9984 {
9985 hddLog(LOGE,
9986 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009987 ret = -EINVAL;
9988 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 }
9990 }
9991 else
9992 {
9993 hddLog(VOS_TRACE_LEVEL_INFO,
9994 "%s: No Assoc Response IE received in set beacon",
9995 __func__);
9996
9997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9999 eANI_BOOLEAN_FALSE) )
10000 {
10001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 }
10004 }
10005
Jeff Johnsone7245742012-09-05 17:12:55 -070010006done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010008 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010009}
Jeff Johnson295189b2012-06-20 16:38:30 -070010010
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 * FUNCTION: wlan_hdd_validate_operation_channel
10013 * called by wlan_hdd_cfg80211_start_bss() and
10014 * wlan_hdd_cfg80211_set_channel()
10015 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 * channel list.
10017 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010018VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 v_U32_t num_ch = 0;
10022 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10023 u32 indx = 0;
10024 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010025 v_U8_t fValidChannel = FALSE, count = 0;
10026 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10029
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010030 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010032 /* Validate the channel */
10033 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010035 if ( channel == rfChannels[count].channelNum )
10036 {
10037 fValidChannel = TRUE;
10038 break;
10039 }
10040 }
10041 if (fValidChannel != TRUE)
10042 {
10043 hddLog(VOS_TRACE_LEVEL_ERROR,
10044 "%s: Invalid Channel [%d]", __func__, channel);
10045 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 }
10047 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010048 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010050 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10051 valid_ch, &num_ch))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
10054 "%s: failed to get valid channel list", __func__);
10055 return VOS_STATUS_E_FAILURE;
10056 }
10057 for (indx = 0; indx < num_ch; indx++)
10058 {
10059 if (channel == valid_ch[indx])
10060 {
10061 break;
10062 }
10063 }
10064
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010065 if (indx >= num_ch)
10066 {
10067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10068 {
10069 eCsrBand band;
10070 unsigned int freq;
10071
10072 sme_GetFreqBand(hHal, &band);
10073
10074 if (eCSR_BAND_5G == band)
10075 {
10076#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10077 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10078 {
10079 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010080 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010081 }
10082 else
10083 {
10084 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010085 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010086 }
10087#else
10088 freq = ieee80211_channel_to_frequency(channel);
10089#endif
10090 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10091 return VOS_STATUS_SUCCESS;
10092 }
10093 }
10094
10095 hddLog(VOS_TRACE_LEVEL_ERROR,
10096 "%s: Invalid Channel [%d]", __func__, channel);
10097 return VOS_STATUS_E_FAILURE;
10098 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010100
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102
Jeff Johnson295189b2012-06-20 16:38:30 -070010103}
10104
Viral Modi3a32cc52013-02-08 11:14:52 -080010105/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010106 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010107 * This function is used to set the channel number
10108 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010109static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010110 struct ieee80211_channel *chan,
10111 enum nl80211_channel_type channel_type
10112 )
10113{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010114 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010115 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010116 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010117 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010118 hdd_context_t *pHddCtx;
10119 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010120
10121 ENTER();
10122
10123 if( NULL == dev )
10124 {
10125 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010127 return -ENODEV;
10128 }
10129 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10132 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10133 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010134 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010135 "%s: device_mode = %s (%d) freq = %d", __func__,
10136 hdd_device_modetoString(pAdapter->device_mode),
10137 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010138
10139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010141 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010143 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010144 }
10145
10146 /*
10147 * Do freq to chan conversion
10148 * TODO: for 11a
10149 */
10150
10151 channel = ieee80211_frequency_to_channel(freq);
10152
10153 /* Check freq range */
10154 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10155 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10156 {
10157 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010158 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010159 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10160 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10161 return -EINVAL;
10162 }
10163
10164 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10165
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010166 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10167 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010168 {
10169 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10170 {
10171 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010172 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010173 return -EINVAL;
10174 }
10175 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10176 "%s: set channel to [%d] for device mode =%d",
10177 __func__, channel,pAdapter->device_mode);
10178 }
10179 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010180 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010181 )
10182 {
10183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10184 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10186
10187 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10188 {
10189 /* Link is up then return cant set channel*/
10190 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010191 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010192 return -EINVAL;
10193 }
10194
10195 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10196 pHddStaCtx->conn_info.operationChannel = channel;
10197 pRoamProfile->ChannelInfo.ChannelList =
10198 &pHddStaCtx->conn_info.operationChannel;
10199 }
10200 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010202 )
10203 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010204 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10205 {
10206 if(VOS_STATUS_SUCCESS !=
10207 wlan_hdd_validate_operation_channel(pAdapter,channel))
10208 {
10209 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010210 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010211 return -EINVAL;
10212 }
10213 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10214 }
10215 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010216 {
10217 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10218
10219 /* If auto channel selection is configured as enable/ 1 then ignore
10220 channel set by supplicant
10221 */
10222 if ( cfg_param->apAutoChannelSelection )
10223 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010224 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10225 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010226 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010227 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10228 __func__, hdd_device_modetoString(pAdapter->device_mode),
10229 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010230 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010231 else
10232 {
10233 if(VOS_STATUS_SUCCESS !=
10234 wlan_hdd_validate_operation_channel(pAdapter,channel))
10235 {
10236 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010237 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010238 return -EINVAL;
10239 }
10240 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10241 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010242 }
10243 }
10244 else
10245 {
10246 hddLog(VOS_TRACE_LEVEL_FATAL,
10247 "%s: Invalid device mode failed to set valid channel", __func__);
10248 return -EINVAL;
10249 }
10250 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010251 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010252}
10253
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010254static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10255 struct net_device *dev,
10256 struct ieee80211_channel *chan,
10257 enum nl80211_channel_type channel_type
10258 )
10259{
10260 int ret;
10261
10262 vos_ssr_protect(__func__);
10263 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10264 vos_ssr_unprotect(__func__);
10265
10266 return ret;
10267}
10268
Anurag Chouhan83026002016-12-13 22:46:21 +053010269#ifdef DHCP_SERVER_OFFLOAD
10270void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10271 VOS_STATUS status)
10272{
10273 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10274
10275 ENTER();
10276
10277 if (NULL == adapter)
10278 {
10279 hddLog(VOS_TRACE_LEVEL_ERROR,
10280 "%s: adapter is NULL",__func__);
10281 return;
10282 }
10283
10284 adapter->dhcp_status.dhcp_offload_status = status;
10285 vos_event_set(&adapter->dhcp_status.vos_event);
10286 return;
10287}
10288
10289/**
10290 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10291 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010292 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010293 *
10294 * Return: None
10295 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010296VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10297 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010298{
10299 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10300 sir_dhcp_srv_offload_info dhcp_srv_info;
10301 tANI_U8 num_entries = 0;
10302 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10303 tANI_U8 num;
10304 tANI_U32 temp;
10305 VOS_STATUS ret;
10306
10307 ENTER();
10308
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010309 if (!re_init) {
10310 ret = wlan_hdd_validate_context(hdd_ctx);
10311 if (0 != ret)
10312 return VOS_STATUS_E_INVAL;
10313 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010314
10315 /* Prepare the request to send to SME */
10316 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10317 if (NULL == dhcp_srv_info) {
10318 hddLog(VOS_TRACE_LEVEL_ERROR,
10319 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10320 return VOS_STATUS_E_NOMEM;
10321 }
10322
10323 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10324
10325 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10326 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10327 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10328 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10329 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10330 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10331
10332 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10333 srv_ip,
10334 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010335 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010336 if (num_entries != IPADDR_NUM_ENTRIES) {
10337 hddLog(VOS_TRACE_LEVEL_ERROR,
10338 "%s: incorrect IP address (%s) assigned for DHCP server!",
10339 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10340 vos_mem_free(dhcp_srv_info);
10341 return VOS_STATUS_E_FAILURE;
10342 }
10343
10344 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10345 hddLog(VOS_TRACE_LEVEL_ERROR,
10346 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10347 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10348 vos_mem_free(dhcp_srv_info);
10349 return VOS_STATUS_E_FAILURE;
10350 }
10351
10352 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10353 hddLog(VOS_TRACE_LEVEL_ERROR,
10354 "%s: invalid IP address (%s)! The last field must be less than 100!",
10355 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10356 vos_mem_free(dhcp_srv_info);
10357 return VOS_STATUS_E_FAILURE;
10358 }
10359
10360 for (num = 0; num < num_entries; num++) {
10361 temp = srv_ip[num];
10362 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10363 }
10364
10365 if (eHAL_STATUS_SUCCESS !=
10366 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10367 hddLog(VOS_TRACE_LEVEL_ERROR,
10368 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10369 vos_mem_free(dhcp_srv_info);
10370 return VOS_STATUS_E_FAILURE;
10371 }
10372
10373 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10374 "%s: enable DHCP Server offload successfully!", __func__);
10375
10376 vos_mem_free(dhcp_srv_info);
10377 return 0;
10378}
10379#endif /* DHCP_SERVER_OFFLOAD */
10380
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010381/*
10382 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10383 * @wiphy_chan: wiphy channel number
10384 * @rfChannel: channel hw value
10385 * @disable: Disable/enable the flags
10386 *
10387 * Modify wiphy flags and cds state if channel is indoor.
10388 *
10389 * Return: void
10390 */
10391void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10392 v_U32_t rfChannel, bool disable)
10393{
10394 v_U32_t channelLoop;
10395 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10396
10397 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10398
10399 if (rfChannels[channelLoop].channelNum == rfChannel) {
10400 channelEnum = (eRfChannels)channelLoop;
10401 break;
10402 }
10403 }
10404
10405 if (INVALID_RF_CHANNEL == channelEnum)
10406 return;
10407
10408 if (disable) {
10409 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10410 wiphy_chan->flags |=
10411 IEEE80211_CHAN_DISABLED;
10412 regChannels[channelEnum].enabled =
10413 NV_CHANNEL_DISABLE;
10414 }
10415 } else {
10416 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10417 wiphy_chan->flags &=
10418 ~IEEE80211_CHAN_DISABLED;
10419 /*
10420 * Indoor channels are marked as DFS
10421 * during regulatory processing
10422 */
10423
10424 regChannels[channelEnum].enabled =
10425 NV_CHANNEL_DFS;
10426 }
10427 }
10428
10429}
10430
10431void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10432 bool disable)
10433{
10434 int band_num;
10435 int chan_num;
10436 v_U32_t rfChannel;
10437 struct ieee80211_channel *wiphy_chan;
10438 struct wiphy *wiphy;
10439
10440 ENTER();
10441 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10442
10443 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010444 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010445
10446 if (wiphy->bands[band_num] == NULL)
10447 continue;
10448
10449 for (chan_num = 0;
10450 chan_num < wiphy->bands[band_num]->n_channels;
10451 chan_num++) {
10452
10453 wiphy_chan =
10454 &(wiphy->bands[band_num]->channels[chan_num]);
10455 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10456
10457 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10458 disable);
10459 }
10460 }
10461 EXIT();
10462}
10463
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010464/*
10465 * FUNCTION: wlan_hdd_disconnect
10466 * This function is used to issue a disconnect request to SME
10467 */
10468int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10469{
10470 int status, result = 0;
10471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10473 long ret;
10474 eConnectionState prev_conn_state;
10475 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10476
10477 ENTER();
10478
10479 status = wlan_hdd_validate_context(pHddCtx);
10480 if (0 != status)
10481 {
10482 return status;
10483 }
10484 /* Indicate sme of disconnect so that in progress connection or preauth
10485 * can be aborted
10486 */
10487 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10488 pAdapter->sessionId);
10489 pHddCtx->isAmpAllowed = VOS_TRUE;
10490
10491 /* Need to apply spin lock before decreasing active sessions
10492 * as there can be chance for double decrement if context switch
10493 * Calls hdd_DisConnectHandler.
10494 */
10495
10496 prev_conn_state = pHddStaCtx->conn_info.connState;
10497
10498 spin_lock_bh(&pAdapter->lock_for_active_session);
10499 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10500 {
10501 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10502 }
10503 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10504 spin_unlock_bh(&pAdapter->lock_for_active_session);
10505 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10506
10507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10508 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10509
10510 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10511
10512 /*
10513 * stop tx queues before deleting STA/BSS context from the firmware.
10514 * tx has to be disabled because the firmware can get busy dropping
10515 * the tx frames after BSS/STA has been deleted and will not send
10516 * back a response resulting in WDI timeout
10517 */
10518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10519 netif_tx_disable(pAdapter->dev);
10520 netif_carrier_off(pAdapter->dev);
10521
10522 wlan_hdd_check_and_stop_mon(pAdapter, true);
10523
10524 /*issue disconnect*/
10525 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10526 pAdapter->sessionId, reason);
10527 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10528 prev_conn_state != eConnectionState_Connecting)
10529 {
10530 hddLog(LOG1,
10531 FL("status = %d, already disconnected"), status);
10532 result = 0;
10533 /*
10534 * Wait here instead of returning directly. This will block the
10535 * next connect command and allow processing of the disconnect
10536 * in SME else we might hit some race conditions leading to SME
10537 * and HDD out of sync. As disconnect is already in progress,
10538 * wait here for 1 sec instead of 5 sec.
10539 */
10540 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10541 goto wait_for_disconnect;
10542 }
10543 /*
10544 * Wait here instead of returning directly, this will block the next
10545 * connect command and allow processing of the scan for ssid and
10546 * the previous connect command in CSR. Else we might hit some
10547 * race conditions leading to SME and HDD out of sync.
10548 */
10549 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10550 {
10551 hddLog(LOG1,
10552 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10553 }
10554 else if ( 0 != status )
10555 {
10556 hddLog(LOGE,
10557 FL("csrRoamDisconnect failure, returned %d"),
10558 (int)status);
10559 result = -EINVAL;
10560 goto disconnected;
10561 }
10562wait_for_disconnect:
10563 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10564 msecs_to_jiffies(wait_time));
10565 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10566 {
10567 hddLog(LOGE,
10568 "%s: Failed to disconnect, timed out", __func__);
10569 result = -ETIMEDOUT;
10570 }
10571disconnected:
10572 hddLog(LOG1,
10573 FL("Set HDD connState to eConnectionState_NotConnected"));
10574 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10575#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10576 /* Sending disconnect event to userspace for kernel version < 3.11
10577 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10578 */
10579 hddLog(LOG1, FL("Send disconnected event to userspace"));
10580
10581 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10582 WLAN_REASON_UNSPECIFIED);
10583#endif
10584
10585 EXIT();
10586 return result;
10587}
10588
10589/*
10590 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10591 * on indoor channel
10592 * @hdd_ctx: pointer to hdd context
10593 *
10594 * STA should be disconnected before starting the SAP if it is on indoor
10595 * channel.
10596 *
10597 * Return: void
10598 */
10599void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10600{
10601
10602 hdd_adapter_t *sta_adapter;
10603 tANI_U8 sta_chan;
10604
10605 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10606
10607 if (!sta_chan) {
10608 hddLog(LOG1, FL("STA not connected"));
10609 return;
10610 }
10611
10612 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10613
10614 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10615 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10616 sta_chan);
10617 return;
10618 }
10619
10620 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10621
10622 if (!sta_adapter) {
10623 hddLog(LOG1, FL("STA adapter doesn't exist"));
10624 return;
10625 }
10626
10627 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10628 /* Issue Disconnect request */
10629 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10630}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010631
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010632int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10633{
10634 struct hdd_cache_channels *cache_chann;
10635 struct wiphy *wiphy;
10636 int freq, status, rfChannel;
10637 int i, band_num, channel_num;
10638 struct ieee80211_channel *wiphy_channel;
10639
10640 ENTER();
10641
10642 if (!hdd_ctx) {
10643 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10644 return -EINVAL;
10645 }
10646
10647 wiphy = hdd_ctx->wiphy;
10648
10649 mutex_lock(&hdd_ctx->cache_channel_lock);
10650
10651 cache_chann = hdd_ctx->orginal_channels;
10652
10653 if (!cache_chann || !cache_chann->num_channels) {
10654 hddLog(VOS_TRACE_LEVEL_INFO,
10655 "%s channel list is NULL or num channels are zero",
10656 __func__);
10657 mutex_unlock(&hdd_ctx->cache_channel_lock);
10658 return -EINVAL;
10659 }
10660
10661 for (i = 0; i < cache_chann->num_channels; i++) {
10662 status = hdd_wlan_get_freq(
10663 cache_chann->channel_info[i].channel_num,
10664 &freq);
10665
10666 for (band_num = 0; band_num < IEEE80211_NUM_BANDS; band_num++) {
10667 for (channel_num = 0; channel_num <
10668 wiphy->bands[band_num]->n_channels;
10669 channel_num++) {
10670 wiphy_channel = &(wiphy->bands[band_num]->
10671 channels[channel_num]);
10672 if (wiphy_channel->center_freq == freq) {
10673 rfChannel = wiphy_channel->hw_value;
10674 /*
10675 *Restore the orginal states
10676 *of the channels
10677 */
10678 vos_nv_set_channel_state(
10679 rfChannel,
10680 cache_chann->
10681 channel_info[i].reg_status);
10682 wiphy_channel->flags =
10683 cache_chann->
10684 channel_info[i].wiphy_status;
10685 break;
10686 }
10687 }
10688 if (channel_num < wiphy->bands[band_num]->n_channels)
10689 break;
10690 }
10691 }
10692
10693 mutex_unlock(&hdd_ctx->cache_channel_lock);
10694
10695 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10696 if (status)
10697 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10698 EXIT();
10699
10700 return 0;
10701}
10702
10703/*
10704 * wlan_hdd_disable_channels() - Cache the the channels
10705 * and current state of the channels from the channel list
10706 * received in the command and disable the channels on the
10707 * wiphy and NV table.
10708 * @hdd_ctx: Pointer to hdd context
10709 *
10710 * @return: 0 on success, Error code on failure
10711 */
10712
10713static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10714{
10715 struct hdd_cache_channels *cache_chann;
10716 struct wiphy *wiphy;
10717 int freq, status, rfChannel;
10718 int i, band_num, band_ch_num;
10719 struct ieee80211_channel *wiphy_channel;
10720
10721 if (!hdd_ctx) {
10722 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10723 return -EINVAL;
10724 }
10725
10726 wiphy = hdd_ctx->wiphy;
10727
10728 mutex_lock(&hdd_ctx->cache_channel_lock);
10729 cache_chann = hdd_ctx->orginal_channels;
10730
10731 if (!cache_chann || !cache_chann->num_channels) {
10732 hddLog(VOS_TRACE_LEVEL_INFO,
10733 "%s channel list is NULL or num channels are zero",
10734 __func__);
10735 mutex_unlock(&hdd_ctx->cache_channel_lock);
10736 return -EINVAL;
10737 }
10738
10739 for (i = 0; i < cache_chann->num_channels; i++) {
10740 status = hdd_wlan_get_freq(
10741 cache_chann->channel_info[i].channel_num,
10742 &freq);
10743
10744 for (band_num = 0; band_num < IEEE80211_NUM_BANDS;
10745 band_num++) {
10746 for (band_ch_num = 0; band_ch_num <
10747 wiphy->bands[band_num]->n_channels;
10748 band_ch_num++) {
10749 wiphy_channel = &(wiphy->bands[band_num]->
10750 channels[band_ch_num]);
10751 if (wiphy_channel->center_freq == freq) {
10752 rfChannel = wiphy_channel->hw_value;
10753 /*
10754 * Cache the current states of
10755 * the channels
10756 */
10757 cache_chann->
10758 channel_info[i].reg_status =
10759 vos_nv_getChannelEnabledState(
10760 rfChannel);
10761
10762 cache_chann->
10763 channel_info[i].wiphy_status =
10764 wiphy_channel->flags;
10765 hddLog(VOS_TRACE_LEVEL_INFO,
10766 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10767 cache_chann->
10768 channel_info[i].channel_num,
10769 cache_chann->
10770 channel_info[i].reg_status,
10771 wiphy_channel->flags);
10772
10773 vos_nv_set_channel_state(
10774 rfChannel,
10775 NV_CHANNEL_DISABLE);
10776 wiphy_channel->flags |=
10777 IEEE80211_CHAN_DISABLED;
10778 break;
10779 }
10780 }
10781 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10782 break;
10783 }
10784 }
10785
10786 mutex_unlock(&hdd_ctx->cache_channel_lock);
10787 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10788 return 0;
10789}
10790
Jeff Johnson295189b2012-06-20 16:38:30 -070010791#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10792static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10793 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010794#else
10795static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10796 struct cfg80211_beacon_data *params,
10797 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010798 enum nl80211_hidden_ssid hidden_ssid,
10799 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010801{
10802 tsap_Config_t *pConfig;
10803 beacon_data_t *pBeacon = NULL;
10804 struct ieee80211_mgmt *pMgmt_frame;
10805 v_U8_t *pIe=NULL;
10806 v_U16_t capab_info;
10807 eCsrAuthType RSNAuthType;
10808 eCsrEncryptionType RSNEncryptType;
10809 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010810 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010811 tpWLAN_SAPEventCB pSapEventCallback;
10812 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010814 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010816 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010818 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010819 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010820 v_BOOL_t MFPCapable = VOS_FALSE;
10821 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010822 v_BOOL_t sapEnable11AC =
10823 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010824 u_int16_t prev_rsn_length = 0;
10825
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 ENTER();
10827
Nitesh Shah9b066282017-06-06 18:05:52 +053010828 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010829 iniConfig = pHddCtx->cfg_ini;
10830
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010831 /* Mark the indoor channel (passive) to disable */
10832 if (iniConfig->disable_indoor_channel) {
10833 hdd_update_indoor_channel(pHddCtx, true);
10834
10835 if (!VOS_IS_STATUS_SUCCESS(
10836 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10837 hdd_update_indoor_channel(pHddCtx, false);
10838 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10839 FL("Can't start BSS: update channel list failed"));
10840 return eHAL_STATUS_FAILURE;
10841 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010842
10843 /* check if STA is on indoor channel */
10844 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10845 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010846 }
10847
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010848 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
10849 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
10850 wlan_hdd_disable_channels(pHddCtx);
10851 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
10852 }
10853
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10855
10856 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10857
10858 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10859
10860 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10861
10862 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10863
10864 //channel is already set in the set_channel Call back
10865 //pConfig->channel = pCommitConfig->channel;
10866
10867 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010868 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10870
10871 pConfig->dtim_period = pBeacon->dtim_period;
10872
Arif Hussain6d2a3322013-11-17 19:50:10 -080010873 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 pConfig->dtim_period);
10875
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010876 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010877 {
10878 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010880 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10881 {
10882 tANI_BOOLEAN restartNeeded;
10883 pConfig->ieee80211d = 1;
10884 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10885 sme_setRegInfo(hHal, pConfig->countryCode);
10886 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10887 }
10888 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010890 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010891 pConfig->ieee80211d = 1;
10892 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10893 sme_setRegInfo(hHal, pConfig->countryCode);
10894 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010895 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010896 else
10897 {
10898 pConfig->ieee80211d = 0;
10899 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010900 /*
10901 * If auto channel is configured i.e. channel is 0,
10902 * so skip channel validation.
10903 */
10904 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10905 {
10906 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10907 {
10908 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010909 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010910 ret = -EINVAL;
10911 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010912 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010913 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010914 }
10915 else
10916 {
10917 if(1 != pHddCtx->is_dynamic_channel_range_set)
10918 {
10919 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10920 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10921 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10922 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010923 pHddCtx->is_dynamic_channel_range_set = 0;
10924 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010925 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010927 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 {
10929 pConfig->ieee80211d = 0;
10930 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010931
10932#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10933 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10934 pConfig->authType = eSAP_OPEN_SYSTEM;
10935 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10936 pConfig->authType = eSAP_SHARED_KEY;
10937 else
10938 pConfig->authType = eSAP_AUTO_SWITCH;
10939#else
10940 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10941 pConfig->authType = eSAP_OPEN_SYSTEM;
10942 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10943 pConfig->authType = eSAP_SHARED_KEY;
10944 else
10945 pConfig->authType = eSAP_AUTO_SWITCH;
10946#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010947
10948 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010949
10950 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010952#ifdef SAP_AUTH_OFFLOAD
10953 /* In case of sap offload, hostapd.conf is configuted with open mode and
10954 * security is configured from ini file. Due to open mode in hostapd.conf
10955 * privacy bit is set to false which will result in not sending,
10956 * data packets as encrypted.
10957 * If enable_sap_auth_offload is enabled in ini and
10958 * sap_auth_offload_sec_type is type of WPA2-PSK,
10959 * driver will set privacy bit to 1.
10960 */
10961 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10962 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10963 pConfig->privacy = VOS_TRUE;
10964#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010965
10966 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10967
10968 /*Set wps station to configured*/
10969 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10970
10971 if(pIe)
10972 {
10973 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10974 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010975 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010976 ret = -EINVAL;
10977 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 }
10979 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10980 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010981 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 /* Check 15 bit of WPS IE as it contain information for wps state
10983 * WPS state
10984 */
10985 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10986 {
10987 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10988 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10989 {
10990 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10991 }
10992 }
10993 }
10994 else
10995 {
10996 pConfig->wps_state = SAP_WPS_DISABLED;
10997 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010998 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010999
c_hpothufe599e92014-06-16 11:38:55 +053011000 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11001 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11002 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11003 eCSR_ENCRYPT_TYPE_NONE;
11004
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011006 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011007 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 WLAN_EID_RSN);
11009 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011010 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011012 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11013 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11014 pConfig->RSNWPAReqIELength);
11015 else
11016 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11017 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011018 /* The actual processing may eventually be more extensive than
11019 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 * by the app.
11021 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11024 &RSNEncryptType,
11025 &mcRSNEncryptType,
11026 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011027 &MFPCapable,
11028 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011029 pConfig->RSNWPAReqIE[1]+2,
11030 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011031
11032 if( VOS_STATUS_SUCCESS == status )
11033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011034 /* Now copy over all the security attributes you have
11035 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 * */
11037 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11038 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11039 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11040 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011041 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011042 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11044 }
11045 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011046
Jeff Johnson295189b2012-06-20 16:38:30 -070011047 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11048 pBeacon->tail, pBeacon->tail_len);
11049
11050 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11051 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011052 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 {
11054 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011055 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011057 if (pConfig->RSNWPAReqIELength <=
11058 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11059 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11060 pIe[1] + 2);
11061 else
11062 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11063 pConfig->RSNWPAReqIELength);
11064
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 }
11066 else
11067 {
11068 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011069 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11070 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11071 pConfig->RSNWPAReqIELength);
11072 else
11073 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11074 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11077 &RSNEncryptType,
11078 &mcRSNEncryptType,
11079 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011080 &MFPCapable,
11081 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011082 pConfig->RSNWPAReqIE[1]+2,
11083 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011084
11085 if( VOS_STATUS_SUCCESS == status )
11086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011087 /* Now copy over all the security attributes you have
11088 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 * */
11090 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11091 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11092 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11093 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011094 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011095 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11097 }
11098 }
11099 }
11100
Kapil Gupta137ef892016-12-13 19:38:00 +053011101 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011102 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011103 ret = -EINVAL;
11104 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011105 }
11106
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11108
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011109#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 if (params->ssid != NULL)
11111 {
11112 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11113 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11114 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11115 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11116 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011117#else
11118 if (ssid != NULL)
11119 {
11120 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11121 pConfig->SSIDinfo.ssid.length = ssid_len;
11122 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11123 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11124 }
11125#endif
11126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011127 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011129
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 /* default value */
11131 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11132 pConfig->num_accept_mac = 0;
11133 pConfig->num_deny_mac = 0;
11134
11135 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11136 pBeacon->tail, pBeacon->tail_len);
11137
11138 /* pIe for black list is following form:
11139 type : 1 byte
11140 length : 1 byte
11141 OUI : 4 bytes
11142 acl type : 1 byte
11143 no of mac addr in black list: 1 byte
11144 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011145 */
11146 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 {
11148 pConfig->SapMacaddr_acl = pIe[6];
11149 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011150 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011152 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11153 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11155 for (i = 0; i < pConfig->num_deny_mac; i++)
11156 {
11157 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11158 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 }
11161 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11162 pBeacon->tail, pBeacon->tail_len);
11163
11164 /* pIe for white list is following form:
11165 type : 1 byte
11166 length : 1 byte
11167 OUI : 4 bytes
11168 acl type : 1 byte
11169 no of mac addr in white list: 1 byte
11170 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011171 */
11172 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 {
11174 pConfig->SapMacaddr_acl = pIe[6];
11175 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011176 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011178 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11179 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11181 for (i = 0; i < pConfig->num_accept_mac; i++)
11182 {
11183 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11184 acl_entry++;
11185 }
11186 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011187
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11189
Jeff Johnsone7245742012-09-05 17:12:55 -070011190#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011191 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011192 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11193 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011194 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11195 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011196 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11197 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011198 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11199 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011200 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011201 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011202 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011203 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011204
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011205 /* If ACS disable and selected channel <= 14
11206 * OR
11207 * ACS enabled and ACS operating band is choosen as 2.4
11208 * AND
11209 * VHT in 2.4G Disabled
11210 * THEN
11211 * Fallback to 11N mode
11212 */
11213 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11214 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011215 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011216 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011217 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011218 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11219 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011220 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11221 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011222 }
11223#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 // ht_capab is not what the name conveys,this is used for protection bitmap
11226 pConfig->ht_capab =
11227 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11228
Kapil Gupta137ef892016-12-13 19:38:00 +053011229 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 {
11231 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011232 ret = -EINVAL;
11233 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 }
11235
11236 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011237 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11239 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011240 pConfig->obssProtEnabled =
11241 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011242
Chet Lanctot8cecea22014-02-11 19:09:36 -080011243#ifdef WLAN_FEATURE_11W
11244 pConfig->mfpCapable = MFPCapable;
11245 pConfig->mfpRequired = MFPRequired;
11246 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11247 pConfig->mfpCapable, pConfig->mfpRequired);
11248#endif
11249
Arif Hussain6d2a3322013-11-17 19:50:10 -080011250 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011252 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11253 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11254 (int)pConfig->channel);
11255 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11256 pConfig->SapHw_mode, pConfig->privacy,
11257 pConfig->authType);
11258 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11259 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11260 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11261 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011262
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
11265 //Bss already started. just return.
11266 //TODO Probably it should update some beacon params.
11267 hddLog( LOGE, "Bss Already started...Ignore the request");
11268 EXIT();
11269 return 0;
11270 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011271
Agarwal Ashish51325b52014-06-16 16:50:49 +053011272 if (vos_max_concurrent_connections_reached()) {
11273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011274 ret = -EINVAL;
11275 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011276 }
11277
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 pConfig->persona = pHostapdAdapter->device_mode;
11279
Peng Xu2446a892014-09-05 17:21:18 +053011280 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11281 if ( NULL != psmeConfig)
11282 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011283 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011284 sme_GetConfigParam(hHal, psmeConfig);
11285 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011286#ifdef WLAN_FEATURE_AP_HT40_24G
11287 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11288 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11289 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11290 {
11291 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11292 sme_UpdateConfig (hHal, psmeConfig);
11293 }
11294#endif
Peng Xu2446a892014-09-05 17:21:18 +053011295 vos_mem_free(psmeConfig);
11296 }
Peng Xuafc34e32014-09-25 13:23:55 +053011297 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011298
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011299 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11300
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 pSapEventCallback = hdd_hostapd_SAPEventCB;
11302 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11303 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11304 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011305 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011306 ret = -EINVAL;
11307 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 }
11309
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011310 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11312
11313 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011314
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 {
11317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011318 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011319 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 VOS_ASSERT(0);
11321 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011322
Jeff Johnson295189b2012-06-20 16:38:30 -070011323 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011324 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11325 VOS_STATUS_SUCCESS)
11326 {
11327 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11328 VOS_ASSERT(0);
11329 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011330 /* Initialize WMM configuation */
11331 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011332 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011333
Anurag Chouhan83026002016-12-13 22:46:21 +053011334#ifdef DHCP_SERVER_OFFLOAD
11335 /* set dhcp server offload */
11336 if (iniConfig->enable_dhcp_srv_offload &&
11337 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011338 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011339 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011340 if (!VOS_IS_STATUS_SUCCESS(status))
11341 {
11342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11343 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011344 vos_event_reset(&pHostapdState->vosEvent);
11345 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11346 status = vos_wait_single_event(&pHostapdState->vosEvent,
11347 10000);
11348 if (!VOS_IS_STATUS_SUCCESS(status)) {
11349 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011350 ret = -EINVAL;
11351 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011352 }
11353 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011354 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011355 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11356 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11357 {
11358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11359 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11360 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011361 vos_event_reset(&pHostapdState->vosEvent);
11362 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11363 status = vos_wait_single_event(&pHostapdState->vosEvent,
11364 10000);
11365 if (!VOS_IS_STATUS_SUCCESS(status)) {
11366 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011367 ret = -EINVAL;
11368 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011369 }
11370 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011371 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011372#ifdef MDNS_OFFLOAD
11373 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011374 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011375 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11376 if (VOS_IS_STATUS_SUCCESS(status))
11377 {
11378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11379 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011380 vos_event_reset(&pHostapdState->vosEvent);
11381 if (VOS_STATUS_SUCCESS ==
11382 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11383 status = vos_wait_single_event(&pHostapdState->vosEvent,
11384 10000);
11385 if (!VOS_IS_STATUS_SUCCESS(status)) {
11386 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011387 ret = -EINVAL;
11388 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011389 }
11390 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011391 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011392 status = vos_wait_single_event(&pHostapdAdapter->
11393 mdns_status.vos_event, 2000);
11394 if (!VOS_IS_STATUS_SUCCESS(status) ||
11395 pHostapdAdapter->mdns_status.mdns_enable_status ||
11396 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11397 pHostapdAdapter->mdns_status.mdns_resp_status)
11398 {
11399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11400 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11401 pHostapdAdapter->mdns_status.mdns_enable_status,
11402 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11403 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011404 vos_event_reset(&pHostapdState->vosEvent);
11405 if (VOS_STATUS_SUCCESS ==
11406 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11407 status = vos_wait_single_event(&pHostapdState->vosEvent,
11408 10000);
11409 if (!VOS_IS_STATUS_SUCCESS(status)) {
11410 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011411 ret = -EINVAL;
11412 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011413 }
11414 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011415 }
11416 }
11417#endif /* MDNS_OFFLOAD */
11418 } else {
11419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11420 ("DHCP Disabled ini %d, FW %d"),
11421 iniConfig->enable_dhcp_srv_offload,
11422 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011423 }
11424#endif /* DHCP_SERVER_OFFLOAD */
11425
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011426#ifdef WLAN_FEATURE_P2P_DEBUG
11427 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11428 {
11429 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11430 {
11431 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11432 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011433 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011434 }
11435 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11436 {
11437 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11438 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011439 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011440 }
11441 }
11442#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011443 /* Check and restart SAP if it is on Unsafe channel */
11444 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011445
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 pHostapdState->bCommit = TRUE;
11447 EXIT();
11448
11449 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011450error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011451 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11452 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011453 /* Revert the indoor to passive marking if START BSS fails */
11454 if (iniConfig->disable_indoor_channel) {
11455 hdd_update_indoor_channel(pHddCtx, false);
11456 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11457 }
11458
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011459 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11460 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011461}
11462
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011463#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011464static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011465 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 struct beacon_parameters *params)
11467{
11468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011469 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011470 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471
11472 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011473
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011474 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11475 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11476 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011477 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11478 hdd_device_modetoString(pAdapter->device_mode),
11479 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011480
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011481 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11482 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011483 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011484 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011485 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011486 }
11487
Agarwal Ashish51325b52014-06-16 16:50:49 +053011488 if (vos_max_concurrent_connections_reached()) {
11489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11490 return -EINVAL;
11491 }
11492
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 )
11496 {
11497 beacon_data_t *old,*new;
11498
11499 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011500
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011502 {
11503 hddLog(VOS_TRACE_LEVEL_WARN,
11504 FL("already beacon info added to session(%d)"),
11505 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011508
11509 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11510
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011511 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 {
11513 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011514 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 return -EINVAL;
11516 }
11517
11518 pAdapter->sessionCtx.ap.beacon = new;
11519
11520 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11521 }
11522
11523 EXIT();
11524 return status;
11525}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011526
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011527static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11528 struct net_device *dev,
11529 struct beacon_parameters *params)
11530{
11531 int ret;
11532
11533 vos_ssr_protect(__func__);
11534 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11535 vos_ssr_unprotect(__func__);
11536
11537 return ret;
11538}
11539
11540static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 struct net_device *dev,
11542 struct beacon_parameters *params)
11543{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11546 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011547 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011548
11549 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011550
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011551 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11552 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11553 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11554 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11555 __func__, hdd_device_modetoString(pAdapter->device_mode),
11556 pAdapter->device_mode);
11557
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011558 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11559 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011560 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011561 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011562 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011563 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011564
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011567 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 {
11569 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011570
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011572
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011574 {
11575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11576 FL("session(%d) old and new heads points to NULL"),
11577 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011579 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011580
11581 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11582
11583 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011585 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 return -EINVAL;
11587 }
11588
11589 pAdapter->sessionCtx.ap.beacon = new;
11590
11591 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11592 }
11593
11594 EXIT();
11595 return status;
11596}
11597
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011598static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11599 struct net_device *dev,
11600 struct beacon_parameters *params)
11601{
11602 int ret;
11603
11604 vos_ssr_protect(__func__);
11605 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11606 vos_ssr_unprotect(__func__);
11607
11608 return ret;
11609}
11610
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011611#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11612
11613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011614static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011616#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011617static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011618 struct net_device *dev)
11619#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011620{
11621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011622 hdd_context_t *pHddCtx = NULL;
11623 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011624 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011625 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011626
11627 ENTER();
11628
11629 if (NULL == pAdapter)
11630 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011632 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 return -ENODEV;
11634 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11637 TRACE_CODE_HDD_CFG80211_STOP_AP,
11638 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011639 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11640 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011641 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011642 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011643 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011644 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011645
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011646 pScanInfo = &pHddCtx->scan_info;
11647
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011648 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11649 __func__, hdd_device_modetoString(pAdapter->device_mode),
11650 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011651
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011652 ret = wlan_hdd_scan_abort(pAdapter);
11653
Girish Gowli4bf7a632014-06-12 13:42:11 +053011654 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011655 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11657 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011658
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011659 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011660 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11662 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011663
Jeff Johnsone7245742012-09-05 17:12:55 -070011664 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011665 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011666 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011667 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011668 }
11669
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011670 /* Delete all associated STAs before stopping AP/P2P GO */
11671 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011672 hdd_hostapd_stop(dev);
11673
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 )
11677 {
11678 beacon_data_t *old;
11679
11680 old = pAdapter->sessionCtx.ap.beacon;
11681
11682 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011683 {
11684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11685 FL("session(%d) beacon data points to NULL"),
11686 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011689
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011691
11692 mutex_lock(&pHddCtx->sap_lock);
11693 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11694 {
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011695 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11696 hdd_wait_for_ecsa_complete(pHddCtx);
Jeff Johnson4416a782013-03-25 14:17:50 -070011697 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011698 {
11699 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11700
11701 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11702
11703 if (!VOS_IS_STATUS_SUCCESS(status))
11704 {
11705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011706 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011708 }
11709 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011711 /* BSS stopped, clear the active sessions for this device mode */
11712 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011713 }
11714 mutex_unlock(&pHddCtx->sap_lock);
11715
11716 if(status != VOS_STATUS_SUCCESS)
11717 {
11718 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011719 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011720 return -EINVAL;
11721 }
11722
Jeff Johnson4416a782013-03-25 14:17:50 -070011723 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11725 ==eHAL_STATUS_FAILURE)
11726 {
11727 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011728 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 }
11730
Jeff Johnson4416a782013-03-25 14:17:50 -070011731 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11733 eANI_BOOLEAN_FALSE) )
11734 {
11735 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011736 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 }
11738
11739 // Reset WNI_CFG_PROBE_RSP Flags
11740 wlan_hdd_reset_prob_rspies(pAdapter);
11741
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011742 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11743
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 pAdapter->sessionCtx.ap.beacon = NULL;
11745 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011746#ifdef WLAN_FEATURE_P2P_DEBUG
11747 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11748 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11749 {
11750 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11751 "GO got removed");
11752 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11753 }
11754#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 }
11756 EXIT();
11757 return status;
11758}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011759
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011760#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11761static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11762 struct net_device *dev)
11763{
11764 int ret;
11765
11766 vos_ssr_protect(__func__);
11767 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11768 vos_ssr_unprotect(__func__);
11769
11770 return ret;
11771}
11772#else
11773static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11774 struct net_device *dev)
11775{
11776 int ret;
11777
11778 vos_ssr_protect(__func__);
11779 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11780 vos_ssr_unprotect(__func__);
11781
11782 return ret;
11783}
11784#endif
11785
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011786#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11787
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011788static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011789 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011790 struct cfg80211_ap_settings *params)
11791{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011792 hdd_adapter_t *pAdapter;
11793 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011794 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011795
11796 ENTER();
11797
Girish Gowlib143d7a2015-02-18 19:39:55 +053011798 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011801 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011802 return -ENODEV;
11803 }
11804
11805 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11806 if (NULL == pAdapter)
11807 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011809 "%s: HDD adapter is Null", __func__);
11810 return -ENODEV;
11811 }
11812
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011813 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11814 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11815 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011816 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11817 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011819 "%s: HDD adapter magic is invalid", __func__);
11820 return -ENODEV;
11821 }
11822
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011823 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11824
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011825 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011826 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011827 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011829 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011830 }
11831
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011832 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11833 __func__, hdd_device_modetoString(pAdapter->device_mode),
11834 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011835
11836 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011837 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011838 )
11839 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011840 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011841
11842 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011843
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011844 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011845 {
11846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11847 FL("already beacon info added to session(%d)"),
11848 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011850 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011851
Girish Gowlib143d7a2015-02-18 19:39:55 +053011852#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11853 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11854 &new,
11855 &params->beacon);
11856#else
11857 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11858 &new,
11859 &params->beacon,
11860 params->dtim_period);
11861#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011862
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011863 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011864 {
11865 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011866 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011867 return -EINVAL;
11868 }
11869 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011871 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11872#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11873 params->channel, params->channel_type);
11874#else
11875 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11876#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011877#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011878 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011879 params->ssid_len, params->hidden_ssid,
11880 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011881 }
11882
11883 EXIT();
11884 return status;
11885}
11886
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011887static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11888 struct net_device *dev,
11889 struct cfg80211_ap_settings *params)
11890{
11891 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011892
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011893 vos_ssr_protect(__func__);
11894 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11895 vos_ssr_unprotect(__func__);
11896
11897 return ret;
11898}
11899
11900static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011901 struct net_device *dev,
11902 struct cfg80211_beacon_data *params)
11903{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011904 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011905 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011906 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011907
11908 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011909
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011910 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11911 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11912 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011913 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011914 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011915
11916 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11917 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011919 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011920 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011921 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011922
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011924 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011925 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011926 {
11927 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011928
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011929 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011930
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011931 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011932 {
11933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11934 FL("session(%d) beacon data points to NULL"),
11935 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011936 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011937 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011938
11939 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11940
11941 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011943 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011944 return -EINVAL;
11945 }
11946
11947 pAdapter->sessionCtx.ap.beacon = new;
11948
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011949 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11950 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011951 }
11952
11953 EXIT();
11954 return status;
11955}
11956
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011957static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11958 struct net_device *dev,
11959 struct cfg80211_beacon_data *params)
11960{
11961 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011962
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011963 vos_ssr_protect(__func__);
11964 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11965 vos_ssr_unprotect(__func__);
11966
11967 return ret;
11968}
11969
11970#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011971
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011972static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 struct net_device *dev,
11974 struct bss_parameters *params)
11975{
11976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011977 hdd_context_t *pHddCtx;
11978 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011979
11980 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011981
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011982 if (NULL == pAdapter)
11983 {
11984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11985 "%s: HDD adapter is Null", __func__);
11986 return -ENODEV;
11987 }
11988 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011989 ret = wlan_hdd_validate_context(pHddCtx);
11990 if (0 != ret)
11991 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011992 return ret;
11993 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11995 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11996 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011997 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11998 __func__, hdd_device_modetoString(pAdapter->device_mode),
11999 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012000
12001 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012003 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012004 {
12005 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12006 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012007 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 {
12009 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012010 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012011 }
12012
12013 EXIT();
12014 return 0;
12015}
12016
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012017static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12018 struct net_device *dev,
12019 struct bss_parameters *params)
12020{
12021 int ret;
12022
12023 vos_ssr_protect(__func__);
12024 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12025 vos_ssr_unprotect(__func__);
12026
12027 return ret;
12028}
Kiet Lam10841362013-11-01 11:36:50 +053012029/* FUNCTION: wlan_hdd_change_country_code_cd
12030* to wait for contry code completion
12031*/
12032void* wlan_hdd_change_country_code_cb(void *pAdapter)
12033{
12034 hdd_adapter_t *call_back_pAdapter = pAdapter;
12035 complete(&call_back_pAdapter->change_country_code);
12036 return NULL;
12037}
12038
Jeff Johnson295189b2012-06-20 16:38:30 -070012039/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012040 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12042 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012043int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012044 struct net_device *ndev,
12045 enum nl80211_iftype type,
12046 u32 *flags,
12047 struct vif_params *params
12048 )
12049{
12050 struct wireless_dev *wdev;
12051 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012052 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012053 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012054 tCsrRoamProfile *pRoamProfile = NULL;
12055 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012056 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 eMib_dot11DesiredBssType connectedBssType;
12058 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012059 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012060
12061 ENTER();
12062
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012063 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012064 {
12065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12066 "%s: Adapter context is null", __func__);
12067 return VOS_STATUS_E_FAILURE;
12068 }
12069
12070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12071 if (!pHddCtx)
12072 {
12073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12074 "%s: HDD context is null", __func__);
12075 return VOS_STATUS_E_FAILURE;
12076 }
12077
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012078 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12079 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12080 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012081 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012082 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012084 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012085 }
12086
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012087 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12088 __func__, hdd_device_modetoString(pAdapter->device_mode),
12089 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012090
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012091 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12092 hddLog(VOS_TRACE_LEVEL_FATAL,
12093 "%s: STA + MON is in progress, cannot change interface",
12094 __func__);
12095 }
12096
Agarwal Ashish51325b52014-06-16 16:50:49 +053012097 if (vos_max_concurrent_connections_reached()) {
12098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12099 return -EINVAL;
12100 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012101 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 wdev = ndev->ieee80211_ptr;
12103
12104#ifdef WLAN_BTAMP_FEATURE
12105 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12106 (NL80211_IFTYPE_ADHOC == type)||
12107 (NL80211_IFTYPE_AP == type)||
12108 (NL80211_IFTYPE_P2P_GO == type))
12109 {
12110 pHddCtx->isAmpAllowed = VOS_FALSE;
12111 // stop AMP traffic
12112 status = WLANBAP_StopAmp();
12113 if(VOS_STATUS_SUCCESS != status )
12114 {
12115 pHddCtx->isAmpAllowed = VOS_TRUE;
12116 hddLog(VOS_TRACE_LEVEL_FATAL,
12117 "%s: Failed to stop AMP", __func__);
12118 return -EINVAL;
12119 }
12120 }
12121#endif //WLAN_BTAMP_FEATURE
12122 /* Reset the current device mode bit mask*/
12123 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12124
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012125 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12126 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12127 (type == NL80211_IFTYPE_P2P_GO)))
12128 {
12129 /* Notify Mode change in case of concurrency.
12130 * Below function invokes TDLS teardown Functionality Since TDLS is
12131 * not Supported in case of concurrency i.e Once P2P session
12132 * is detected disable offchannel and teardown TDLS links
12133 */
12134 hddLog(LOG1,
12135 FL("Device mode = %d Interface type = %d"),
12136 pAdapter->device_mode, type);
12137 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12138 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012139
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012142 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 )
12144 {
12145 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012146 if (!pWextState)
12147 {
12148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12149 "%s: pWextState is null", __func__);
12150 return VOS_STATUS_E_FAILURE;
12151 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012152 pRoamProfile = &pWextState->roamProfile;
12153 LastBSSType = pRoamProfile->BSSType;
12154
12155 switch (type)
12156 {
12157 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 hddLog(VOS_TRACE_LEVEL_INFO,
12160 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12161 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012162#ifdef WLAN_FEATURE_11AC
12163 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12164 {
12165 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12166 }
12167#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012168 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012169 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012170 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012171 //Check for sub-string p2p to confirm its a p2p interface
12172 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012173 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012174#ifdef FEATURE_WLAN_TDLS
12175 mutex_lock(&pHddCtx->tdls_lock);
12176 wlan_hdd_tdls_exit(pAdapter, TRUE);
12177 mutex_unlock(&pHddCtx->tdls_lock);
12178#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012179 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12180 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12181 }
12182 else
12183 {
12184 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012186 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012188
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 case NL80211_IFTYPE_ADHOC:
12190 hddLog(VOS_TRACE_LEVEL_INFO,
12191 "%s: setting interface Type to ADHOC", __func__);
12192 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12193 pRoamProfile->phyMode =
12194 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012195 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012197 hdd_set_ibss_ops( pAdapter );
12198 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012199
12200 status = hdd_sta_id_hash_attach(pAdapter);
12201 if (VOS_STATUS_SUCCESS != status) {
12202 hddLog(VOS_TRACE_LEVEL_ERROR,
12203 FL("Failed to initialize hash for IBSS"));
12204 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 break;
12206
12207 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 {
12210 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12211 "%s: setting interface Type to %s", __func__,
12212 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12213
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012214 //Cancel any remain on channel for GO mode
12215 if (NL80211_IFTYPE_P2P_GO == type)
12216 {
12217 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12218 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012219 if (NL80211_IFTYPE_AP == type)
12220 {
12221 /* As Loading WLAN Driver one interface being created for p2p device
12222 * address. This will take one HW STA and the max number of clients
12223 * that can connect to softAP will be reduced by one. so while changing
12224 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12225 * interface as it is not required in SoftAP mode.
12226 */
12227
12228 // Get P2P Adapter
12229 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12230
12231 if (pP2pAdapter)
12232 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012233 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012234 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012235 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12236 }
12237 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012238 //Disable IMPS & BMPS for SAP/GO
12239 if(VOS_STATUS_E_FAILURE ==
12240 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12241 {
12242 //Fail to Exit BMPS
12243 VOS_ASSERT(0);
12244 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012245
12246 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12247
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012248#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012249
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012250 /* A Mutex Lock is introduced while changing the mode to
12251 * protect the concurrent access for the Adapters by TDLS
12252 * module.
12253 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012254 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012255#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012257 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12260 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012261#ifdef FEATURE_WLAN_TDLS
12262 mutex_unlock(&pHddCtx->tdls_lock);
12263#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012264 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12265 (pConfig->apRandomBssidEnabled))
12266 {
12267 /* To meet Android requirements create a randomized
12268 MAC address of the form 02:1A:11:Fx:xx:xx */
12269 get_random_bytes(&ndev->dev_addr[3], 3);
12270 ndev->dev_addr[0] = 0x02;
12271 ndev->dev_addr[1] = 0x1A;
12272 ndev->dev_addr[2] = 0x11;
12273 ndev->dev_addr[3] |= 0xF0;
12274 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12275 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012276 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12277 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012278 }
12279
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 hdd_set_ap_ops( pAdapter->dev );
12281
Kiet Lam10841362013-11-01 11:36:50 +053012282 /* This is for only SAP mode where users can
12283 * control country through ini.
12284 * P2P GO follows station country code
12285 * acquired during the STA scanning. */
12286 if((NL80211_IFTYPE_AP == type) &&
12287 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12288 {
12289 int status = 0;
12290 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12291 "%s: setting country code from INI ", __func__);
12292 init_completion(&pAdapter->change_country_code);
12293 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12294 (void *)(tSmeChangeCountryCallback)
12295 wlan_hdd_change_country_code_cb,
12296 pConfig->apCntryCode, pAdapter,
12297 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012298 eSIR_FALSE,
12299 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012300 if (eHAL_STATUS_SUCCESS == status)
12301 {
12302 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012303 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012304 &pAdapter->change_country_code,
12305 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012306 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012307 {
12308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012309 FL("SME Timed out while setting country code %ld"),
12310 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012311
12312 if (pHddCtx->isLogpInProgress)
12313 {
12314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12315 "%s: LOGP in Progress. Ignore!!!", __func__);
12316 return -EAGAIN;
12317 }
Kiet Lam10841362013-11-01 11:36:50 +053012318 }
12319 }
12320 else
12321 {
12322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012323 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012324 return -EINVAL;
12325 }
12326 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012327 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 if(status != VOS_STATUS_SUCCESS)
12329 {
12330 hddLog(VOS_TRACE_LEVEL_FATAL,
12331 "%s: Error initializing the ap mode", __func__);
12332 return -EINVAL;
12333 }
12334 hdd_set_conparam(1);
12335
Nirav Shah7e3c8132015-06-22 23:51:42 +053012336 status = hdd_sta_id_hash_attach(pAdapter);
12337 if (VOS_STATUS_SUCCESS != status)
12338 {
12339 hddLog(VOS_TRACE_LEVEL_ERROR,
12340 FL("Failed to initialize hash for AP"));
12341 return -EINVAL;
12342 }
12343
Jeff Johnson295189b2012-06-20 16:38:30 -070012344 /*interface type changed update in wiphy structure*/
12345 if(wdev)
12346 {
12347 wdev->iftype = type;
12348 pHddCtx->change_iface = type;
12349 }
12350 else
12351 {
12352 hddLog(VOS_TRACE_LEVEL_ERROR,
12353 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12354 return -EINVAL;
12355 }
12356 goto done;
12357 }
12358
12359 default:
12360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12361 __func__);
12362 return -EOPNOTSUPP;
12363 }
12364 }
12365 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012366 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 )
12368 {
12369 switch(type)
12370 {
12371 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012374
12375 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012376#ifdef FEATURE_WLAN_TDLS
12377
12378 /* A Mutex Lock is introduced while changing the mode to
12379 * protect the concurrent access for the Adapters by TDLS
12380 * module.
12381 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012382 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012383#endif
c_hpothu002231a2015-02-05 14:58:51 +053012384 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012386 //Check for sub-string p2p to confirm its a p2p interface
12387 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012388 {
12389 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12390 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12391 }
12392 else
12393 {
12394 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012396 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012397
12398 /* set con_mode to STA only when no SAP concurrency mode */
12399 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12400 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012402 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12403 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012404#ifdef FEATURE_WLAN_TDLS
12405 mutex_unlock(&pHddCtx->tdls_lock);
12406#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012407 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 if( VOS_STATUS_SUCCESS != status )
12409 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012410 /* In case of JB, for P2P-GO, only change interface will be called,
12411 * This is the right place to enable back bmps_imps()
12412 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012413 if (pHddCtx->hdd_wlan_suspended)
12414 {
12415 hdd_set_pwrparams(pHddCtx);
12416 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012417 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 goto done;
12419 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12423 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 goto done;
12425 default:
12426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12427 __func__);
12428 return -EOPNOTSUPP;
12429
12430 }
12431
12432 }
12433 else
12434 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012435 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12436 __func__, hdd_device_modetoString(pAdapter->device_mode),
12437 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 return -EOPNOTSUPP;
12439 }
12440
12441
12442 if(pRoamProfile)
12443 {
12444 if ( LastBSSType != pRoamProfile->BSSType )
12445 {
12446 /*interface type changed update in wiphy structure*/
12447 wdev->iftype = type;
12448
12449 /*the BSS mode changed, We need to issue disconnect
12450 if connected or in IBSS disconnect state*/
12451 if ( hdd_connGetConnectedBssType(
12452 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12453 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12454 {
12455 /*need to issue a disconnect to CSR.*/
12456 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12457 if( eHAL_STATUS_SUCCESS ==
12458 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12459 pAdapter->sessionId,
12460 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12461 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012462 ret = wait_for_completion_interruptible_timeout(
12463 &pAdapter->disconnect_comp_var,
12464 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12465 if (ret <= 0)
12466 {
12467 hddLog(VOS_TRACE_LEVEL_ERROR,
12468 FL("wait on disconnect_comp_var failed %ld"), ret);
12469 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012470 }
12471 }
12472 }
12473 }
12474
12475done:
12476 /*set bitmask based on updated value*/
12477 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012478
12479 /* Only STA mode support TM now
12480 * all other mode, TM feature should be disabled */
12481 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12482 (~VOS_STA & pHddCtx->concurrency_mode) )
12483 {
12484 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12485 }
12486
Jeff Johnson295189b2012-06-20 16:38:30 -070012487#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012488 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012489 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 {
12491 //we are ok to do AMP
12492 pHddCtx->isAmpAllowed = VOS_TRUE;
12493 }
12494#endif //WLAN_BTAMP_FEATURE
12495 EXIT();
12496 return 0;
12497}
12498
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012499/*
12500 * FUNCTION: wlan_hdd_cfg80211_change_iface
12501 * wrapper function to protect the actual implementation from SSR.
12502 */
12503int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12504 struct net_device *ndev,
12505 enum nl80211_iftype type,
12506 u32 *flags,
12507 struct vif_params *params
12508 )
12509{
12510 int ret;
12511
12512 vos_ssr_protect(__func__);
12513 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12514 vos_ssr_unprotect(__func__);
12515
12516 return ret;
12517}
12518
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012519#ifdef FEATURE_WLAN_TDLS
12520static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012521 struct net_device *dev,
12522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12523 const u8 *mac,
12524#else
12525 u8 *mac,
12526#endif
12527 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012528{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012529 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012530 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012531 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012532 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012533 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012534 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012535
12536 ENTER();
12537
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012538 if (!dev) {
12539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12540 return -EINVAL;
12541 }
12542
12543 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12544 if (!pAdapter) {
12545 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12546 return -EINVAL;
12547 }
12548
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012549 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012550 {
12551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12552 "Invalid arguments");
12553 return -EINVAL;
12554 }
Hoonki Lee27511902013-03-14 18:19:06 -070012555
12556 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12557 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12558 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012560 "%s: TDLS mode is disabled OR not enabled in FW."
12561 MAC_ADDRESS_STR " Request declined.",
12562 __func__, MAC_ADDR_ARRAY(mac));
12563 return -ENOTSUPP;
12564 }
12565
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012566 if (pHddCtx->isLogpInProgress)
12567 {
12568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12569 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012570 wlan_hdd_tdls_set_link_status(pAdapter,
12571 mac,
12572 eTDLS_LINK_IDLE,
12573 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012574 return -EBUSY;
12575 }
12576
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012577 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012578 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012579
12580 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012582 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12583 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012584 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012585 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012586 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012587
12588 /* in add station, we accept existing valid staId if there is */
12589 if ((0 == update) &&
12590 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12591 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012592 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012594 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012595 " link_status %d. staId %d. add station ignored.",
12596 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012597 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012598 return 0;
12599 }
12600 /* in change station, we accept only when staId is valid */
12601 if ((1 == update) &&
12602 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12603 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12604 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012605 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012607 "%s: " MAC_ADDRESS_STR
12608 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012609 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12610 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12611 mutex_unlock(&pHddCtx->tdls_lock);
12612 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012613 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012614 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012615
12616 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012617 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012618 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12620 "%s: " MAC_ADDRESS_STR
12621 " TDLS setup is ongoing. Request declined.",
12622 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012623 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012624 }
12625
12626 /* first to check if we reached to maximum supported TDLS peer.
12627 TODO: for now, return -EPERM looks working fine,
12628 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012629 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12630 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012631 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12633 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012634 " TDLS Max peer already connected. Request declined."
12635 " Num of peers (%d), Max allowed (%d).",
12636 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12637 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012638 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012639 }
12640 else
12641 {
12642 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012643 mutex_lock(&pHddCtx->tdls_lock);
12644 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012645 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012646 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012647 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12649 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12650 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012651 return -EPERM;
12652 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012653 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012654 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012655 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012656 wlan_hdd_tdls_set_link_status(pAdapter,
12657 mac,
12658 eTDLS_LINK_CONNECTING,
12659 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012660
Jeff Johnsond75fe012013-04-06 10:53:06 -070012661 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012662 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012663 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012665 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012666 if(StaParams->htcap_present)
12667 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012669 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012671 "ht_capa->extended_capabilities: %0x",
12672 StaParams->HTCap.extendedHtCapInfo);
12673 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012675 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012677 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012678 if(StaParams->vhtcap_present)
12679 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012681 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12682 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12683 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12684 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012685 {
12686 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012688 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012690 "[%d]: %x ", i, StaParams->supported_rates[i]);
12691 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012692 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012693 else if ((1 == update) && (NULL == StaParams))
12694 {
12695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12696 "%s : update is true, but staParams is NULL. Error!", __func__);
12697 return -EPERM;
12698 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012699
12700 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12701
12702 if (!update)
12703 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012704 /*Before adding sta make sure that device exited from BMPS*/
12705 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12706 {
12707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12708 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12709 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12710 if (status != VOS_STATUS_SUCCESS) {
12711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12712 }
12713 }
12714
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012715 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012716 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012717 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012718 hddLog(VOS_TRACE_LEVEL_ERROR,
12719 FL("Failed to add TDLS peer STA. Enable Bmps"));
12720 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012721 return -EPERM;
12722 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012723 }
12724 else
12725 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012726 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012727 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012728 if (ret != eHAL_STATUS_SUCCESS) {
12729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12730 return -EPERM;
12731 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012732 }
12733
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012734 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012735 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12736
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012737 mutex_lock(&pHddCtx->tdls_lock);
12738 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12739
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012740 if ((pTdlsPeer != NULL) &&
12741 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012742 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012743 hddLog(VOS_TRACE_LEVEL_ERROR,
12744 FL("peer link status %u"), pTdlsPeer->link_status);
12745 mutex_unlock(&pHddCtx->tdls_lock);
12746 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012747 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012748 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012749
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012750 if (ret <= 0)
12751 {
12752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12753 "%s: timeout waiting for tdls add station indication %ld",
12754 __func__, ret);
12755 goto error;
12756 }
12757
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012758 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12759 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012761 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012762 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012763 }
12764
12765 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012766
12767error:
Atul Mittal115287b2014-07-08 13:26:33 +053012768 wlan_hdd_tdls_set_link_status(pAdapter,
12769 mac,
12770 eTDLS_LINK_IDLE,
12771 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012772 return -EPERM;
12773
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012774}
12775#endif
12776
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012777VOS_STATUS wlan_hdd_send_sta_authorized_event(
12778 hdd_adapter_t *adapter,
12779 hdd_context_t *hdd_ctx,
12780 const v_MACADDR_t *mac_addr)
12781{
12782 struct sk_buff *vendor_event;
12783 uint32_t sta_flags = 0;
12784 VOS_STATUS status;
12785
12786 ENTER();
12787
12788 if (!hdd_ctx) {
12789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12790 return -EINVAL;
12791 }
12792
12793 vendor_event =
12794 cfg80211_vendor_event_alloc(
12795 hdd_ctx->wiphy, &adapter->wdev, sizeof(sta_flags) +
12796 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12797 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12798 GFP_KERNEL);
12799 if (!vendor_event) {
12800 hddLog(VOS_TRACE_LEVEL_ERROR,
12801 FL("cfg80211_vendor_event_alloc failed"));
12802 return -EINVAL;
12803 }
12804
12805 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12806
12807 status = nla_put_u32(vendor_event,
12808 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12809 sta_flags);
12810 if (status) {
12811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12812 kfree_skb(vendor_event);
12813 return VOS_STATUS_E_FAILURE;
12814 }
12815 status = nla_put(vendor_event,
12816 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12817 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12818 if (status) {
12819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12820 kfree_skb(vendor_event);
12821 return VOS_STATUS_E_FAILURE;
12822 }
12823
12824 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
12825
12826 EXIT();
12827 return 0;
12828}
12829
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012830static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012832#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12833 const u8 *mac,
12834#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012835 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012836#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012837 struct station_parameters *params)
12838{
12839 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012840 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012841 hdd_context_t *pHddCtx;
12842 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012844 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012845#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012846 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012847 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012848 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012849 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012850#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012851
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012852 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012853
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012854 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012855 if ((NULL == pAdapter))
12856 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012858 "invalid adapter ");
12859 return -EINVAL;
12860 }
12861
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012862 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12863 TRACE_CODE_HDD_CHANGE_STATION,
12864 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012865 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012866
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012867 ret = wlan_hdd_validate_context(pHddCtx);
12868 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012869 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012870 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012871 }
12872
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012873 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12874
12875 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012876 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012877 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12878 "invalid HDD station context");
12879 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012880 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12882
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012883 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12884 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012886 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012888 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012889 WLANTL_STA_AUTHENTICATED);
12890
Gopichand Nakkala29149562013-05-10 21:43:41 +053012891 if (status != VOS_STATUS_SUCCESS)
12892 {
12893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12894 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12895 return -EINVAL;
12896 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012897 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
12898 &STAMacAddress);
12899 if (status != VOS_STATUS_SUCCESS)
12900 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012901 }
12902 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012903 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12904 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012905#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012906 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12907 StaParams.capability = params->capability;
12908 StaParams.uapsd_queues = params->uapsd_queues;
12909 StaParams.max_sp = params->max_sp;
12910
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012911 /* Convert (first channel , number of channels) tuple to
12912 * the total list of channels. This goes with the assumption
12913 * that if the first channel is < 14, then the next channels
12914 * are an incremental of 1 else an incremental of 4 till the number
12915 * of channels.
12916 */
12917 if (0 != params->supported_channels_len) {
12918 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12919 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12920 {
12921 int wifi_chan_index;
12922 StaParams.supported_channels[j] = params->supported_channels[i];
12923 wifi_chan_index =
12924 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12925 no_of_channels = params->supported_channels[i+1];
12926 for(k=1; k <= no_of_channels; k++)
12927 {
12928 StaParams.supported_channels[j+1] =
12929 StaParams.supported_channels[j] + wifi_chan_index;
12930 j+=1;
12931 }
12932 }
12933 StaParams.supported_channels_len = j;
12934 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012935 if (params->supported_oper_classes_len >
12936 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12938 "received oper classes:%d, resetting it to max supported %d",
12939 params->supported_oper_classes_len,
12940 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12941 params->supported_oper_classes_len =
12942 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12943 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012944 vos_mem_copy(StaParams.supported_oper_classes,
12945 params->supported_oper_classes,
12946 params->supported_oper_classes_len);
12947 StaParams.supported_oper_classes_len =
12948 params->supported_oper_classes_len;
12949
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012950 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12952 "received extn capabilities:%d, resetting it to max supported",
12953 params->ext_capab_len);
12954 params->ext_capab_len = sizeof(StaParams.extn_capability);
12955 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012956 if (0 != params->ext_capab_len)
12957 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012958 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012959
12960 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012961 {
12962 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012963 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012964 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012965
12966 StaParams.supported_rates_len = params->supported_rates_len;
12967
12968 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12969 * The supported_rates array , for all the structures propogating till Add Sta
12970 * to the firmware has to be modified , if the supplicant (ieee80211) is
12971 * modified to send more rates.
12972 */
12973
12974 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12975 */
12976 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12977 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12978
12979 if (0 != StaParams.supported_rates_len) {
12980 int i = 0;
12981 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12982 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012984 "Supported Rates with Length %d", StaParams.supported_rates_len);
12985 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012987 "[%d]: %0x", i, StaParams.supported_rates[i]);
12988 }
12989
12990 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012991 {
12992 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012993 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012994 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012995
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012996 if (0 != params->ext_capab_len ) {
12997 /*Define A Macro : TODO Sunil*/
12998 if ((1<<4) & StaParams.extn_capability[3]) {
12999 isBufSta = 1;
13000 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013001 /* TDLS Channel Switching Support */
13002 if ((1<<6) & StaParams.extn_capability[3]) {
13003 isOffChannelSupported = 1;
13004 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013005 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013006
13007 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013008 (params->ht_capa || params->vht_capa ||
13009 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013010 /* TDLS Peer is WME/QoS capable */
13011 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013012
13013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13014 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13015 __func__, isQosWmmSta, StaParams.htcap_present);
13016
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013017 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13018 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013019 isOffChannelSupported,
13020 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013021
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013022 if (VOS_STATUS_SUCCESS != status) {
13023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13024 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13025 return -EINVAL;
13026 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013027 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13028
13029 if (VOS_STATUS_SUCCESS != status) {
13030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13031 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13032 return -EINVAL;
13033 }
13034 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013035#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013036 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013037 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013038 return status;
13039}
13040
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13042static int wlan_hdd_change_station(struct wiphy *wiphy,
13043 struct net_device *dev,
13044 const u8 *mac,
13045 struct station_parameters *params)
13046#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013047static int wlan_hdd_change_station(struct wiphy *wiphy,
13048 struct net_device *dev,
13049 u8 *mac,
13050 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013051#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013052{
13053 int ret;
13054
13055 vos_ssr_protect(__func__);
13056 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13057 vos_ssr_unprotect(__func__);
13058
13059 return ret;
13060}
13061
Jeff Johnson295189b2012-06-20 16:38:30 -070013062/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013063 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013064 * This function is used to initialize the key information
13065 */
13066#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013067static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 struct net_device *ndev,
13069 u8 key_index, bool pairwise,
13070 const u8 *mac_addr,
13071 struct key_params *params
13072 )
13073#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013074static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 struct net_device *ndev,
13076 u8 key_index, const u8 *mac_addr,
13077 struct key_params *params
13078 )
13079#endif
13080{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 tCsrRoamSetKey setKey;
13083 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013084 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013085 v_U32_t roamId= 0xFF;
13086 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013087 hdd_hostapd_state_t *pHostapdState;
13088 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013089 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013090 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013091 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013092 v_MACADDR_t *peerMacAddr;
13093 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013094 uint8_t staid = HDD_MAX_STA_COUNT;
13095 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013096
13097 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013098
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13100 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13101 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013102 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13103 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013104 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013105 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013106 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013107 }
13108
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13110 __func__, hdd_device_modetoString(pAdapter->device_mode),
13111 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013112
13113 if (CSR_MAX_NUM_KEY <= key_index)
13114 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013116 key_index);
13117
13118 return -EINVAL;
13119 }
13120
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013121 if (CSR_MAX_KEY_LEN < params->key_len)
13122 {
13123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13124 params->key_len);
13125
13126 return -EINVAL;
13127 }
13128
Jingxiang Gec438aea2017-10-26 16:44:00 +080013129 if (CSR_MAX_RSC_LEN < params->seq_len)
13130 {
13131 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13132 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013133
13134 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013135 }
13136
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013137 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013138 "%s: called with key index = %d & key length %d & seq length %d",
13139 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013140
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013141 peerMacAddr = (v_MACADDR_t *)mac_addr;
13142
Jeff Johnson295189b2012-06-20 16:38:30 -070013143 /*extract key idx, key len and key*/
13144 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13145 setKey.keyId = key_index;
13146 setKey.keyLength = params->key_len;
13147 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013148 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013149
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013150 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013151 {
13152 case WLAN_CIPHER_SUITE_WEP40:
13153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13154 break;
13155
13156 case WLAN_CIPHER_SUITE_WEP104:
13157 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13158 break;
13159
13160 case WLAN_CIPHER_SUITE_TKIP:
13161 {
13162 u8 *pKey = &setKey.Key[0];
13163 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13164
13165 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13166
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013167 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013168
13169 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013170 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 |--------------|----------|----------|
13172 <---16bytes---><--8bytes--><--8bytes-->
13173
13174 */
13175 /*Sme expects the 32 bytes key to be in the below order
13176
13177 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013178 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013179 |--------------|----------|----------|
13180 <---16bytes---><--8bytes--><--8bytes-->
13181 */
13182 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013183 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013184
13185 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013186 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013187
13188 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013189 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013190
13191
13192 break;
13193 }
13194
13195 case WLAN_CIPHER_SUITE_CCMP:
13196 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13197 break;
13198
13199#ifdef FEATURE_WLAN_WAPI
13200 case WLAN_CIPHER_SUITE_SMS4:
13201 {
13202 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13203 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13204 params->key, params->key_len);
13205 return 0;
13206 }
13207#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013208
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013209#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 case WLAN_CIPHER_SUITE_KRK:
13211 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13212 break;
13213#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013214
13215#ifdef WLAN_FEATURE_11W
13216 case WLAN_CIPHER_SUITE_AES_CMAC:
13217 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013218 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013219#endif
13220
Jeff Johnson295189b2012-06-20 16:38:30 -070013221 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013223 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013224 status = -EOPNOTSUPP;
13225 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 }
13227
13228 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13229 __func__, setKey.encType);
13230
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013231 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13233 (!pairwise)
13234#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013235 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013236#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013237 )
13238 {
13239 /* set group key*/
13240 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13241 "%s- %d: setting Broadcast key",
13242 __func__, __LINE__);
13243 setKey.keyDirection = eSIR_RX_ONLY;
13244 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13245 }
13246 else
13247 {
13248 /* set pairwise key*/
13249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13250 "%s- %d: setting pairwise key",
13251 __func__, __LINE__);
13252 setKey.keyDirection = eSIR_TX_RX;
13253 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013254 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013255 }
13256 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13257 {
13258 setKey.keyDirection = eSIR_TX_RX;
13259 /*Set the group key*/
13260 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13261 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013262
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013263 if ( 0 != status )
13264 {
13265 hddLog(VOS_TRACE_LEVEL_ERROR,
13266 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013267 status = -EINVAL;
13268 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013269 }
13270 /*Save the keys here and call sme_RoamSetKey for setting
13271 the PTK after peer joins the IBSS network*/
13272 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13273 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013274 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013275 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013276 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13277 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13278 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013279 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013280 if( pHostapdState->bssState == BSS_START )
13281 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013282 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13283 vos_status = wlan_hdd_check_ula_done(pAdapter);
13284
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013285 if (peerMacAddr && (pairwise_set_key == true))
13286 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013287
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013288 if ( vos_status != VOS_STATUS_SUCCESS )
13289 {
13290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13291 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13292 __LINE__, vos_status );
13293
13294 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13295
13296 status = -EINVAL;
13297 goto end;
13298 }
13299
Jeff Johnson295189b2012-06-20 16:38:30 -070013300 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13301
13302 if ( status != eHAL_STATUS_SUCCESS )
13303 {
13304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13305 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13306 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013307 status = -EINVAL;
13308 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013309 }
13310 }
13311
13312 /* Saving WEP keys */
13313 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13314 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13315 {
13316 //Save the wep key in ap context. Issue setkey after the BSS is started.
13317 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13318 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13319 }
13320 else
13321 {
13322 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013323 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013324 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13325 }
13326 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013327 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13328 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 {
13330 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13331 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13332
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013333#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13334 if (!pairwise)
13335#else
13336 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13337#endif
13338 {
13339 /* set group key*/
13340 if (pHddStaCtx->roam_info.deferKeyComplete)
13341 {
13342 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13343 "%s- %d: Perform Set key Complete",
13344 __func__, __LINE__);
13345 hdd_PerformRoamSetKeyComplete(pAdapter);
13346 }
13347 }
13348
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013349 if (pairwise_set_key == true)
13350 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013351
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13353
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013354 pWextState->roamProfile.Keys.defaultIndex = key_index;
13355
13356
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013357 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013358 params->key, params->key_len);
13359
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013360
Jeff Johnson295189b2012-06-20 16:38:30 -070013361 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13362
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013363 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013365 __func__, setKey.peerMac[0], setKey.peerMac[1],
13366 setKey.peerMac[2], setKey.peerMac[3],
13367 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 setKey.keyDirection);
13369
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013370 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013371
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013372 if ( vos_status != VOS_STATUS_SUCCESS )
13373 {
13374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13376 __LINE__, vos_status );
13377
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013378 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013379
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013380 status = -EINVAL;
13381 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013382
13383 }
13384
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013385#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013386 /* The supplicant may attempt to set the PTK once pre-authentication
13387 is done. Save the key in the UMAC and include it in the ADD BSS
13388 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013389 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013390 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013391 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013392 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13393 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013394 status = 0;
13395 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013396 }
13397 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13398 {
13399 hddLog(VOS_TRACE_LEVEL_ERROR,
13400 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013401 status = -EINVAL;
13402 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013403 }
13404#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013405
13406 /* issue set key request to SME*/
13407 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13408 pAdapter->sessionId, &setKey, &roamId );
13409
13410 if ( 0 != status )
13411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013412 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13414 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013415 status = -EINVAL;
13416 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 }
13418
13419
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013420 /* in case of IBSS as there was no information available about WEP keys during
13421 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013422 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013423 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13424 !( ( IW_AUTH_KEY_MGMT_802_1X
13425 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13427 )
13428 &&
13429 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13430 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13431 )
13432 )
13433 {
13434 setKey.keyDirection = eSIR_RX_ONLY;
13435 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13436
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013437 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013438 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013439 __func__, setKey.peerMac[0], setKey.peerMac[1],
13440 setKey.peerMac[2], setKey.peerMac[3],
13441 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 setKey.keyDirection);
13443
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013444 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 pAdapter->sessionId, &setKey, &roamId );
13446
13447 if ( 0 != status )
13448 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013449 hddLog(VOS_TRACE_LEVEL_ERROR,
13450 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013451 __func__, status);
13452 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013453 status = -EINVAL;
13454 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 }
13456 }
13457 }
13458
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013459 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013460 for (i = 0; i < params->seq_len; i++) {
13461 rsc_counter |= (params->seq[i] << i*8);
13462 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013463 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13464 }
13465
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013466end:
13467 /* Need to clear any trace of key value in the memory.
13468 * Thus zero out the memory even though it is local
13469 * variable.
13470 */
13471 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013472 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013473 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013474}
13475
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13477static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13478 struct net_device *ndev,
13479 u8 key_index, bool pairwise,
13480 const u8 *mac_addr,
13481 struct key_params *params
13482 )
13483#else
13484static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13485 struct net_device *ndev,
13486 u8 key_index, const u8 *mac_addr,
13487 struct key_params *params
13488 )
13489#endif
13490{
13491 int ret;
13492 vos_ssr_protect(__func__);
13493#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13494 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13495 mac_addr, params);
13496#else
13497 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13498 params);
13499#endif
13500 vos_ssr_unprotect(__func__);
13501
13502 return ret;
13503}
13504
Jeff Johnson295189b2012-06-20 16:38:30 -070013505/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013506 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 * This function is used to get the key information
13508 */
13509#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013510static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013511 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013512 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013513 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013514 const u8 *mac_addr, void *cookie,
13515 void (*callback)(void *cookie, struct key_params*)
13516 )
13517#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013518static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013519 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013520 struct net_device *ndev,
13521 u8 key_index, const u8 *mac_addr, void *cookie,
13522 void (*callback)(void *cookie, struct key_params*)
13523 )
13524#endif
13525{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013526 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013527 hdd_wext_state_t *pWextState = NULL;
13528 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013529 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013530 hdd_context_t *pHddCtx;
13531 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013532
13533 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013534
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013535 if (NULL == pAdapter)
13536 {
13537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13538 "%s: HDD adapter is Null", __func__);
13539 return -ENODEV;
13540 }
13541
13542 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13543 ret = wlan_hdd_validate_context(pHddCtx);
13544 if (0 != ret)
13545 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013546 return ret;
13547 }
13548
13549 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13550 pRoamProfile = &(pWextState->roamProfile);
13551
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013552 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13553 __func__, hdd_device_modetoString(pAdapter->device_mode),
13554 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013555
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 memset(&params, 0, sizeof(params));
13557
13558 if (CSR_MAX_NUM_KEY <= key_index)
13559 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013560 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013562 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013563
13564 switch(pRoamProfile->EncryptionType.encryptionType[0])
13565 {
13566 case eCSR_ENCRYPT_TYPE_NONE:
13567 params.cipher = IW_AUTH_CIPHER_NONE;
13568 break;
13569
13570 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13571 case eCSR_ENCRYPT_TYPE_WEP40:
13572 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13573 break;
13574
13575 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13576 case eCSR_ENCRYPT_TYPE_WEP104:
13577 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13578 break;
13579
13580 case eCSR_ENCRYPT_TYPE_TKIP:
13581 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13582 break;
13583
13584 case eCSR_ENCRYPT_TYPE_AES:
13585 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13586 break;
13587
13588 default:
13589 params.cipher = IW_AUTH_CIPHER_NONE;
13590 break;
13591 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013592
c_hpothuaaf19692014-05-17 17:01:48 +053013593 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13594 TRACE_CODE_HDD_CFG80211_GET_KEY,
13595 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013596
Jeff Johnson295189b2012-06-20 16:38:30 -070013597 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13598 params.seq_len = 0;
13599 params.seq = NULL;
13600 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13601 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013602 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 return 0;
13604}
13605
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013606#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13607static int wlan_hdd_cfg80211_get_key(
13608 struct wiphy *wiphy,
13609 struct net_device *ndev,
13610 u8 key_index, bool pairwise,
13611 const u8 *mac_addr, void *cookie,
13612 void (*callback)(void *cookie, struct key_params*)
13613 )
13614#else
13615static int wlan_hdd_cfg80211_get_key(
13616 struct wiphy *wiphy,
13617 struct net_device *ndev,
13618 u8 key_index, const u8 *mac_addr, void *cookie,
13619 void (*callback)(void *cookie, struct key_params*)
13620 )
13621#endif
13622{
13623 int ret;
13624
13625 vos_ssr_protect(__func__);
13626#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13627 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13628 mac_addr, cookie, callback);
13629#else
13630 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13631 callback);
13632#endif
13633 vos_ssr_unprotect(__func__);
13634
13635 return ret;
13636}
13637
Jeff Johnson295189b2012-06-20 16:38:30 -070013638/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013639 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013640 * This function is used to delete the key information
13641 */
13642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013643static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645 u8 key_index,
13646 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 const u8 *mac_addr
13648 )
13649#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013650static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 struct net_device *ndev,
13652 u8 key_index,
13653 const u8 *mac_addr
13654 )
13655#endif
13656{
13657 int status = 0;
13658
13659 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013660 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 //it is observed that this is invalidating peer
13662 //key index whenever re-key is done. This is affecting data link.
13663 //It should be ok to ignore del_key.
13664#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13666 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13668 tCsrRoamSetKey setKey;
13669 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 ENTER();
13672
13673 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13674 __func__,pAdapter->device_mode);
13675
13676 if (CSR_MAX_NUM_KEY <= key_index)
13677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013679 key_index);
13680
13681 return -EINVAL;
13682 }
13683
13684 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13685 setKey.keyId = key_index;
13686
13687 if (mac_addr)
13688 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13689 else
13690 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13691
13692 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13693
13694 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013695 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013696 )
13697 {
13698
13699 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13701 if( pHostapdState->bssState == BSS_START)
13702 {
13703 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013704
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 if ( status != eHAL_STATUS_SUCCESS )
13706 {
13707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13708 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13709 __LINE__, status );
13710 }
13711 }
13712 }
13713 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013714 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 )
13716 {
13717 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13718
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13720
13721 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013722 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013723 __func__, setKey.peerMac[0], setKey.peerMac[1],
13724 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013725 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013726 if(pAdapter->sessionCtx.station.conn_info.connState ==
13727 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013728 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013729 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013730 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013731
Jeff Johnson295189b2012-06-20 16:38:30 -070013732 if ( 0 != status )
13733 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013734 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013735 "%s: sme_RoamSetKey failure, returned %d",
13736 __func__, status);
13737 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13738 return -EINVAL;
13739 }
13740 }
13741 }
13742#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013743 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 return status;
13745}
13746
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13748static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13749 struct net_device *ndev,
13750 u8 key_index,
13751 bool pairwise,
13752 const u8 *mac_addr
13753 )
13754#else
13755static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13756 struct net_device *ndev,
13757 u8 key_index,
13758 const u8 *mac_addr
13759 )
13760#endif
13761{
13762 int ret;
13763
13764 vos_ssr_protect(__func__);
13765#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13766 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13767 mac_addr);
13768#else
13769 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13770#endif
13771 vos_ssr_unprotect(__func__);
13772
13773 return ret;
13774}
13775
Jeff Johnson295189b2012-06-20 16:38:30 -070013776/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013777 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 * This function is used to set the default tx key index
13779 */
13780#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013781static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013782 struct net_device *ndev,
13783 u8 key_index,
13784 bool unicast, bool multicast)
13785#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013786static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 struct net_device *ndev,
13788 u8 key_index)
13789#endif
13790{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013792 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013793 hdd_wext_state_t *pWextState;
13794 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013795 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013796
13797 ENTER();
13798
Gopichand Nakkala29149562013-05-10 21:43:41 +053013799 if ((NULL == pAdapter))
13800 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013802 "invalid adapter");
13803 return -EINVAL;
13804 }
13805
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013806 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13807 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13808 pAdapter->sessionId, key_index));
13809
Gopichand Nakkala29149562013-05-10 21:43:41 +053013810 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13811 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13812
13813 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13814 {
13815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13816 "invalid Wext state or HDD context");
13817 return -EINVAL;
13818 }
13819
Arif Hussain6d2a3322013-11-17 19:50:10 -080013820 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013822
Jeff Johnson295189b2012-06-20 16:38:30 -070013823 if (CSR_MAX_NUM_KEY <= key_index)
13824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013826 key_index);
13827
13828 return -EINVAL;
13829 }
13830
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013831 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13832 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013833 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013835 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013836 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013837
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013840 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013842 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013843 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013844#ifdef FEATURE_WLAN_WAPI
13845 (eCSR_ENCRYPT_TYPE_WPI !=
13846 pHddStaCtx->conn_info.ucEncryptionType) &&
13847#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013848 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013849 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013851 {
13852 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 tCsrRoamSetKey setKey;
13856 v_U32_t roamId= 0xFF;
13857 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013858
13859 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013861
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 Keys->defaultIndex = (u8)key_index;
13863 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13864 setKey.keyId = key_index;
13865 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866
13867 vos_mem_copy(&setKey.Key[0],
13868 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013870
Gopichand Nakkala29149562013-05-10 21:43:41 +053013871 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013872
13873 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013874 &pHddStaCtx->conn_info.bssId[0],
13875 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013876
Gopichand Nakkala29149562013-05-10 21:43:41 +053013877 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13878 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13879 eCSR_ENCRYPT_TYPE_WEP104)
13880 {
13881 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13882 even though ap is configured for WEP-40 encryption. In this canse the key length
13883 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13884 type(104) and switching encryption type to 40*/
13885 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13886 eCSR_ENCRYPT_TYPE_WEP40;
13887 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13888 eCSR_ENCRYPT_TYPE_WEP40;
13889 }
13890
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013891 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013893
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013895 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013896 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013897
Jeff Johnson295189b2012-06-20 16:38:30 -070013898 if ( 0 != status )
13899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013900 hddLog(VOS_TRACE_LEVEL_ERROR,
13901 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013902 status);
13903 return -EINVAL;
13904 }
13905 }
13906 }
13907
13908 /* In SoftAp mode setting key direction for default mode */
13909 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13910 {
13911 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13912 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13913 (eCSR_ENCRYPT_TYPE_AES !=
13914 pWextState->roamProfile.EncryptionType.encryptionType[0])
13915 )
13916 {
13917 /* Saving key direction for default key index to TX default */
13918 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13919 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13920 }
13921 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013922 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013923 return status;
13924}
13925
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013926#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13927static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13928 struct net_device *ndev,
13929 u8 key_index,
13930 bool unicast, bool multicast)
13931#else
13932static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13933 struct net_device *ndev,
13934 u8 key_index)
13935#endif
13936{
13937 int ret;
13938 vos_ssr_protect(__func__);
13939#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13940 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13941 multicast);
13942#else
13943 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13944#endif
13945 vos_ssr_unprotect(__func__);
13946
13947 return ret;
13948}
13949
Jeff Johnson295189b2012-06-20 16:38:30 -070013950/*
13951 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13952 * This function is used to inform the BSS details to nl80211 interface.
13953 */
13954static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13955 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13956{
13957 struct net_device *dev = pAdapter->dev;
13958 struct wireless_dev *wdev = dev->ieee80211_ptr;
13959 struct wiphy *wiphy = wdev->wiphy;
13960 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13961 int chan_no;
13962 int ie_length;
13963 const char *ie;
13964 unsigned int freq;
13965 struct ieee80211_channel *chan;
13966 int rssi = 0;
13967 struct cfg80211_bss *bss = NULL;
13968
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 if( NULL == pBssDesc )
13970 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013971 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 return bss;
13973 }
13974
13975 chan_no = pBssDesc->channelId;
13976 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13977 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13978
13979 if( NULL == ie )
13980 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013981 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013982 return bss;
13983 }
13984
13985#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13986 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13987 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013988 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 }
13990 else
13991 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013992 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013993 }
13994#else
13995 freq = ieee80211_channel_to_frequency(chan_no);
13996#endif
13997
13998 chan = __ieee80211_get_channel(wiphy, freq);
13999
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014000 if (!chan) {
14001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14002 return NULL;
14003 }
14004
Abhishek Singhaee43942014-06-16 18:55:47 +053014005 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014006
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014007 return cfg80211_inform_bss(wiphy, chan,
14008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14009 CFG80211_BSS_FTYPE_UNKNOWN,
14010#endif
14011 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014012 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 pBssDesc->capabilityInfo,
14014 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014015 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014016}
14017
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014018/*
14019 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14020 * interface that BSS might have been lost.
14021 * @pAdapter: adaptor
14022 * @bssid: bssid which might have been lost
14023 *
14024 * Return: bss which is unlinked from kernel cache
14025 */
14026struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14027 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14028{
14029 struct net_device *dev = pAdapter->dev;
14030 struct wireless_dev *wdev = dev->ieee80211_ptr;
14031 struct wiphy *wiphy = wdev->wiphy;
14032 struct cfg80211_bss *bss = NULL;
14033
Abhishek Singh5a597e62016-12-05 15:16:30 +053014034 bss = hdd_get_bss_entry(wiphy,
14035 NULL, bssid,
14036 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014037 if (bss == NULL) {
14038 hddLog(LOGE, FL("BSS not present"));
14039 } else {
14040 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14041 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14042 cfg80211_unlink_bss(wiphy, bss);
14043 }
14044 return bss;
14045}
Jeff Johnson295189b2012-06-20 16:38:30 -070014046
14047
14048/*
14049 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14050 * This function is used to inform the BSS details to nl80211 interface.
14051 */
14052struct cfg80211_bss*
14053wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14054 tSirBssDescription *bss_desc
14055 )
14056{
14057 /*
14058 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14059 already exists in bss data base of cfg80211 for that particular BSS ID.
14060 Using cfg80211_inform_bss_frame to update the bss entry instead of
14061 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14062 now there is no possibility to get the mgmt(probe response) frame from PE,
14063 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14064 cfg80211_inform_bss_frame.
14065 */
14066 struct net_device *dev = pAdapter->dev;
14067 struct wireless_dev *wdev = dev->ieee80211_ptr;
14068 struct wiphy *wiphy = wdev->wiphy;
14069 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014070#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14071 qcom_ie_age *qie_age = NULL;
14072 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14073#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 const char *ie =
14077 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14078 unsigned int freq;
14079 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014080 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014081 struct cfg80211_bss *bss_status = NULL;
14082 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14083 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014084 hdd_context_t *pHddCtx;
14085 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014086#ifdef WLAN_OPEN_SOURCE
14087 struct timespec ts;
14088#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014089
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014090
Wilson Yangf80a0542013-10-07 13:02:37 -070014091 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14092 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014093 if (0 != status)
14094 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014095 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014096 }
14097
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014098 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014099 if (!mgmt)
14100 {
14101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14102 "%s: memory allocation failed ", __func__);
14103 return NULL;
14104 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014105
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014107
14108#ifdef WLAN_OPEN_SOURCE
14109 /* Android does not want the timestamp from the frame.
14110 Instead it wants a monotonic increasing value */
14111 get_monotonic_boottime(&ts);
14112 mgmt->u.probe_resp.timestamp =
14113 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14114#else
14115 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14117 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014118
14119#endif
14120
Jeff Johnson295189b2012-06-20 16:38:30 -070014121 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14122 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014123
14124#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14125 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14126 /* Assuming this is the last IE, copy at the end */
14127 ie_length -=sizeof(qcom_ie_age);
14128 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14129 qie_age->element_id = QCOM_VENDOR_IE_ID;
14130 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14131 qie_age->oui_1 = QCOM_OUI1;
14132 qie_age->oui_2 = QCOM_OUI2;
14133 qie_age->oui_3 = QCOM_OUI3;
14134 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014135 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14136 * bss related timestamp is in units of ms. Due to this when scan results
14137 * are sent to lowi the scan age is high.To address this, send age in units
14138 * of 1/10 ms.
14139 */
14140 qie_age->age = (vos_timer_get_system_time() -
14141 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014142#endif
14143
Jeff Johnson295189b2012-06-20 16:38:30 -070014144 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014145 if (bss_desc->fProbeRsp)
14146 {
14147 mgmt->frame_control |=
14148 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14149 }
14150 else
14151 {
14152 mgmt->frame_control |=
14153 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14154 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014155
14156#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014157 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014158 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014160 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014162 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014163 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014164
14165 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014166 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 }
14168 else
14169 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14171 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014172 kfree(mgmt);
14173 return NULL;
14174 }
14175#else
14176 freq = ieee80211_channel_to_frequency(chan_no);
14177#endif
14178 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014179 /*when the band is changed on the fly using the GUI, three things are done
14180 * 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)
14181 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14182 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14183 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14184 * and discards the channels correponding to previous band and calls back with zero bss results.
14185 * 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
14186 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14187 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14188 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14189 * So drop the bss and continue to next bss.
14190 */
14191 if(chan == NULL)
14192 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014193 hddLog(VOS_TRACE_LEVEL_ERROR,
14194 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14195 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014196 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014197 return NULL;
14198 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014199 /*To keep the rssi icon of the connected AP in the scan window
14200 *and the rssi icon of the wireless networks in sync
14201 * */
14202 if (( eConnectionState_Associated ==
14203 pAdapter->sessionCtx.station.conn_info.connState ) &&
14204 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14205 pAdapter->sessionCtx.station.conn_info.bssId,
14206 WNI_CFG_BSSID_LEN)) &&
14207 (pHddCtx->hdd_wlan_suspended == FALSE))
14208 {
14209 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14210 rssi = (pAdapter->rssi * 100);
14211 }
14212 else
14213 {
14214 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14215 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014216
Nirav Shah20ac06f2013-12-12 18:14:06 +053014217 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014218 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14219 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014220
Jeff Johnson295189b2012-06-20 16:38:30 -070014221 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14222 frame_len, rssi, GFP_KERNEL);
14223 kfree(mgmt);
14224 return bss_status;
14225}
14226
14227/*
14228 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14229 * This function is used to update the BSS data base of CFG8011
14230 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014231struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014232 tCsrRoamInfo *pRoamInfo
14233 )
14234{
14235 tCsrRoamConnectedProfile roamProfile;
14236 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14237 struct cfg80211_bss *bss = NULL;
14238
14239 ENTER();
14240
14241 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14242 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14243
14244 if (NULL != roamProfile.pBssDesc)
14245 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014246 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14247 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014248
14249 if (NULL == bss)
14250 {
14251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14252 __func__);
14253 }
14254
14255 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14256 }
14257 else
14258 {
14259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14260 __func__);
14261 }
14262 return bss;
14263}
14264
14265/*
14266 * FUNCTION: wlan_hdd_cfg80211_update_bss
14267 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014268static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14269 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014271{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014272 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014273 tCsrScanResultInfo *pScanResult;
14274 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014275 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 tScanResultHandle pResult;
14277 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014278 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014279 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014281
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014282 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14283 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14284 NO_SESSION, pAdapter->sessionId));
14285
Wilson Yangf80a0542013-10-07 13:02:37 -070014286 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014287 ret = wlan_hdd_validate_context(pHddCtx);
14288 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014290 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014291 }
14292
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014293 if (pAdapter->request != NULL)
14294 {
14295 if ((pAdapter->request->n_ssids == 1)
14296 && (pAdapter->request->ssids != NULL)
14297 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14298 is_p2p_scan = true;
14299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014300 /*
14301 * start getting scan results and populate cgf80211 BSS database
14302 */
14303 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14304
14305 /* no scan results */
14306 if (NULL == pResult)
14307 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014308 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14309 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014310 wlan_hdd_get_frame_logs(pAdapter,
14311 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014312 return status;
14313 }
14314
14315 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14316
14317 while (pScanResult)
14318 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014319 /*
14320 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14321 * entry already exists in bss data base of cfg80211 for that
14322 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14323 * bss entry instead of cfg80211_inform_bss, But this call expects
14324 * mgmt packet as input. As of now there is no possibility to get
14325 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014326 * ieee80211_mgmt(probe response) and passing to c
14327 * fg80211_inform_bss_frame.
14328 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014329 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14330 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14331 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014332 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14333 continue; //Skip the non p2p bss entries
14334 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014335 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14336 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014337
Jeff Johnson295189b2012-06-20 16:38:30 -070014338
14339 if (NULL == bss_status)
14340 {
14341 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014342 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014343 }
14344 else
14345 {
Yue Maf49ba872013-08-19 12:04:25 -070014346 cfg80211_put_bss(
14347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14348 wiphy,
14349#endif
14350 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014351 }
14352
14353 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14354 }
14355
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014356 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014357 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014358 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014359}
14360
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014361void
14362hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14363{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014364 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014365 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014366} /****** end hddPrintMacAddr() ******/
14367
14368void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014369hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014370{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014371 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014372 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014373 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14374 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14375 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014376} /****** end hddPrintPmkId() ******/
14377
14378//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14379//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14380
14381//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14382//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14383
14384#define dump_bssid(bssid) \
14385 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014386 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14387 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014388 }
14389
14390#define dump_pmkid(pMac, pmkid) \
14391 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014392 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14393 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014394 }
14395
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014396#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014397/*
14398 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14399 * This function is used to notify the supplicant of a new PMKSA candidate.
14400 */
14401int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014402 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014403 int index, bool preauth )
14404{
Jeff Johnsone7245742012-09-05 17:12:55 -070014405#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014406 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014407 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014408
14409 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014410 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014411
14412 if( NULL == pRoamInfo )
14413 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014414 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014415 return -EINVAL;
14416 }
14417
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014418 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14419 {
14420 dump_bssid(pRoamInfo->bssid);
14421 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014422 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014423 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014424#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014425 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014426}
14427#endif //FEATURE_WLAN_LFR
14428
Yue Maef608272013-04-08 23:09:17 -070014429#ifdef FEATURE_WLAN_LFR_METRICS
14430/*
14431 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14432 * 802.11r/LFR metrics reporting function to report preauth initiation
14433 *
14434 */
14435#define MAX_LFR_METRICS_EVENT_LENGTH 100
14436VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14437 tCsrRoamInfo *pRoamInfo)
14438{
14439 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14440 union iwreq_data wrqu;
14441
14442 ENTER();
14443
14444 if (NULL == pAdapter)
14445 {
14446 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14447 return VOS_STATUS_E_FAILURE;
14448 }
14449
14450 /* create the event */
14451 memset(&wrqu, 0, sizeof(wrqu));
14452 memset(metrics_notification, 0, sizeof(metrics_notification));
14453
14454 wrqu.data.pointer = metrics_notification;
14455 wrqu.data.length = scnprintf(metrics_notification,
14456 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14457 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14458
14459 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14460
14461 EXIT();
14462
14463 return VOS_STATUS_SUCCESS;
14464}
14465
14466/*
14467 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14468 * 802.11r/LFR metrics reporting function to report preauth completion
14469 * or failure
14470 */
14471VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14472 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14473{
14474 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14475 union iwreq_data wrqu;
14476
14477 ENTER();
14478
14479 if (NULL == pAdapter)
14480 {
14481 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14482 return VOS_STATUS_E_FAILURE;
14483 }
14484
14485 /* create the event */
14486 memset(&wrqu, 0, sizeof(wrqu));
14487 memset(metrics_notification, 0, sizeof(metrics_notification));
14488
14489 scnprintf(metrics_notification, sizeof(metrics_notification),
14490 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14491 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14492
14493 if (1 == preauth_status)
14494 strncat(metrics_notification, " TRUE", 5);
14495 else
14496 strncat(metrics_notification, " FALSE", 6);
14497
14498 wrqu.data.pointer = metrics_notification;
14499 wrqu.data.length = strlen(metrics_notification);
14500
14501 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14502
14503 EXIT();
14504
14505 return VOS_STATUS_SUCCESS;
14506}
14507
14508/*
14509 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14510 * 802.11r/LFR metrics reporting function to report handover initiation
14511 *
14512 */
14513VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14514 tCsrRoamInfo *pRoamInfo)
14515{
14516 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14517 union iwreq_data wrqu;
14518
14519 ENTER();
14520
14521 if (NULL == pAdapter)
14522 {
14523 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14524 return VOS_STATUS_E_FAILURE;
14525 }
14526
14527 /* create the event */
14528 memset(&wrqu, 0, sizeof(wrqu));
14529 memset(metrics_notification, 0, sizeof(metrics_notification));
14530
14531 wrqu.data.pointer = metrics_notification;
14532 wrqu.data.length = scnprintf(metrics_notification,
14533 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14534 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14535
14536 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14537
14538 EXIT();
14539
14540 return VOS_STATUS_SUCCESS;
14541}
14542#endif
14543
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014544
14545/**
14546 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14547 * @scan_req: scan request to be checked
14548 *
14549 * Return: true or false
14550 */
14551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14552static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14553 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014554 *scan_req, hdd_context_t
14555 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014556{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014557 if (!scan_req || !scan_req->wiphy ||
14558 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014559 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14560 return false;
14561 }
14562 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14563 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14564 return false;
14565 }
14566 return true;
14567}
14568#else
14569static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14570 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014571 *scan_req, hdd_context_t
14572 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014573{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014574 if (!scan_req || !scan_req->wiphy ||
14575 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014576 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14577 return false;
14578 }
14579 return true;
14580}
14581#endif
14582
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14584/**
14585 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14586 * @adapter: Pointer to the adapter
14587 * @req : Scan request
14588 * @aborted : true scan aborted false scan success
14589 *
14590 * This function notifies scan done to cfg80211
14591 *
14592 * Return: none
14593 */
14594static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14595 struct cfg80211_scan_request *req,
14596 bool aborted)
14597{
14598 struct cfg80211_scan_info info = {
14599 .aborted = aborted
14600 };
14601
14602 if (adapter->dev->flags & IFF_UP)
14603 cfg80211_scan_done(req, &info);
14604 else
14605 hddLog(LOGW,
14606 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14607}
14608#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14609/**
14610 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14611 * @adapter: Pointer to the adapter
14612 * @req : Scan request
14613 * @aborted : true scan aborted false scan success
14614 *
14615 * This function notifies scan done to cfg80211
14616 *
14617 * Return: none
14618 */
14619static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14620 struct cfg80211_scan_request *req,
14621 bool aborted)
14622{
14623 if (adapter->dev->flags & IFF_UP)
14624 cfg80211_scan_done(req, aborted);
14625 else
14626 hddLog(LOGW,
14627 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14628}
14629#else
14630/**
14631 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14632 * @adapter: Pointer to the adapter
14633 * @req : Scan request
14634 * @aborted : true scan aborted false scan success
14635 *
14636 * This function notifies scan done to cfg80211
14637 *
14638 * Return: none
14639 */
14640static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14641 struct cfg80211_scan_request *req,
14642 bool aborted)
14643{
14644 cfg80211_scan_done(req, aborted);
14645}
14646#endif
14647
Mukul Sharmab392b642017-08-17 17:45:29 +053014648#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014649/*
14650 * FUNCTION: hdd_cfg80211_scan_done_callback
14651 * scanning callback function, called after finishing scan
14652 *
14653 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014654static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014655 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14656{
14657 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014658 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014660 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014661 struct cfg80211_scan_request *req = NULL;
14662 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014663 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014664 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014665 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014666
14667 ENTER();
14668
c_manjee1b4ab9a2016-10-26 11:36:55 +053014669 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14670 !pAdapter->dev) {
14671 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14672 return 0;
14673 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014674 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014675 if (NULL == pHddCtx) {
14676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014677 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014678 }
14679
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014680#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014681 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014682 {
14683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014684 }
14685#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014686 pScanInfo = &pHddCtx->scan_info;
14687
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014689 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014690 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014691 __func__, halHandle, pContext, (int) scanId, (int) status);
14692
Kiet Lamac06e2c2013-10-23 16:25:07 +053014693 pScanInfo->mScanPendingCounter = 0;
14694
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014696 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014697 &pScanInfo->scan_req_completion_event,
14698 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014699 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014701 hddLog(VOS_TRACE_LEVEL_ERROR,
14702 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014704 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014705 }
14706
Yue Maef608272013-04-08 23:09:17 -070014707 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014708 {
14709 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014710 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 }
14712
14713 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014714 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014715 {
14716 hddLog(VOS_TRACE_LEVEL_INFO,
14717 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014718 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 (int) scanId);
14720 }
14721
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014723 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014724#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014725 {
14726 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14727 pAdapter);
14728 if (0 > ret)
14729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014730 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014731
Jeff Johnson295189b2012-06-20 16:38:30 -070014732 /* If any client wait scan result through WEXT
14733 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014734 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 {
14736 /* The other scan request waiting for current scan finish
14737 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014738 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014739 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014740 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 }
14742 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014743 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 {
14745 struct net_device *dev = pAdapter->dev;
14746 union iwreq_data wrqu;
14747 int we_event;
14748 char *msg;
14749
14750 memset(&wrqu, '\0', sizeof(wrqu));
14751 we_event = SIOCGIWSCAN;
14752 msg = NULL;
14753 wireless_send_event(dev, we_event, &wrqu, msg);
14754 }
14755 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014756 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014757
14758 /* Get the Scan Req */
14759 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014760 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014761
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014762 /* Scan is no longer pending */
14763 pScanInfo->mScanPending = VOS_FALSE;
14764
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014765 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014767#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014769 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014770#endif
14771
14772 if (pAdapter->dev) {
14773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14774 pAdapter->dev->name);
14775 }
mukul sharmae7041822015-12-03 15:09:21 +053014776 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014777 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 }
14779
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014780 /* last_scan_timestamp is used to decide if new scan
14781 * is needed or not on station interface. If last station
14782 * scan time and new station scan time is less then
14783 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014784 * Also only last_scan_timestamp is updated here last_scan_channellist
14785 * is updated on receiving scan request itself to make sure kernel
14786 * allocated scan request(scan_req) object is not dereferenced here,
14787 * because interface down, where kernel frees scan_req, may happen any
14788 * time while driver is processing scan_done_callback. So it's better
14789 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014790 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014791 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14792 if (status == eCSR_SCAN_SUCCESS)
14793 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14794 else {
14795 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14796 sizeof(pHddCtx->scan_info.last_scan_channelList));
14797 pHddCtx->scan_info.last_scan_numChannels = 0;
14798 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014799 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014800 }
14801
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014802 /*
14803 * cfg80211_scan_done informing NL80211 about completion
14804 * of scanning
14805 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014806 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14807 {
14808 aborted = true;
14809 }
mukul sharmae7041822015-12-03 15:09:21 +053014810
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014811#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014812 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14813 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014814#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014815 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014816
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014817 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014818
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014819allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014820 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14821 ) && (pHddCtx->spoofMacAddr.isEnabled
14822 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014823 /* Generate new random mac addr for next scan */
14824 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014825
14826 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14827 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014828 }
14829
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014830 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014831 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014832
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014833 /* Acquire wakelock to handle the case where APP's tries to suspend
14834 * immediatly after the driver gets connect request(i.e after scan)
14835 * from supplicant, this result in app's is suspending and not able
14836 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014837 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014838
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014840 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014841#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014842#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014843 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014844#endif
14845
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 EXIT();
14847 return 0;
14848}
14849
14850/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014851 * FUNCTION: hdd_isConnectionInProgress
14852 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014853 *
14854 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014855v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14856 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014857{
14858 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14859 hdd_station_ctx_t *pHddStaCtx = NULL;
14860 hdd_adapter_t *pAdapter = NULL;
14861 VOS_STATUS status = 0;
14862 v_U8_t staId = 0;
14863 v_U8_t *staMac = NULL;
14864
14865 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14866
14867 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14868 {
14869 pAdapter = pAdapterNode->pAdapter;
14870
14871 if( pAdapter )
14872 {
14873 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014874 "%s: Adapter with device mode %s (%d) exists",
14875 __func__, hdd_device_modetoString(pAdapter->device_mode),
14876 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014877 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014878 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14879 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14880 (eConnectionState_Connecting ==
14881 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14882 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014883 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014884 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014885 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014886 if (session_id && reason)
14887 {
14888 *session_id = pAdapter->sessionId;
14889 *reason = eHDD_CONNECTION_IN_PROGRESS;
14890 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014891 return VOS_TRUE;
14892 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014893 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014894 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014895 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014896 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014897 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014898 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014899 if (session_id && reason)
14900 {
14901 *session_id = pAdapter->sessionId;
14902 *reason = eHDD_REASSOC_IN_PROGRESS;
14903 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014904 return VOS_TRUE;
14905 }
14906 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014907 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14908 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014909 {
14910 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14911 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014912 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014913 {
14914 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014915 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014916 "%s: client " MAC_ADDRESS_STR
14917 " is in the middle of WPS/EAPOL exchange.", __func__,
14918 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014919 if (session_id && reason)
14920 {
14921 *session_id = pAdapter->sessionId;
14922 *reason = eHDD_EAPOL_IN_PROGRESS;
14923 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014924 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014925 }
14926 }
14927 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14928 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14929 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014930 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14931 ptSapContext pSapCtx = NULL;
14932 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14933 if(pSapCtx == NULL){
14934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14935 FL("psapCtx is NULL"));
14936 return VOS_FALSE;
14937 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014938 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14939 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014940 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14941 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014942 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014943 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014944
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014945 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014946 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14947 "middle of WPS/EAPOL exchange.", __func__,
14948 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014949 if (session_id && reason)
14950 {
14951 *session_id = pAdapter->sessionId;
14952 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14953 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014954 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014955 }
14956 }
14957 }
14958 }
14959 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14960 pAdapterNode = pNext;
14961 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014962 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014963}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014964
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014965/**
14966 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14967 * to the Scan request
14968 * @scanRequest: Pointer to the csr scan request
14969 * @request: Pointer to the scan request from supplicant
14970 *
14971 * Return: None
14972 */
14973#ifdef CFG80211_SCAN_BSSID
14974static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14975 struct cfg80211_scan_request *request)
14976{
14977 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14978}
14979#else
14980static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14981 struct cfg80211_scan_request *request)
14982{
14983}
14984#endif
14985
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014986/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014987 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014988 * this scan respond to scan trigger and update cfg80211 scan database
14989 * later, scan dump command can be used to recieve scan results
14990 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014991int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014992#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14993 struct net_device *dev,
14994#endif
14995 struct cfg80211_scan_request *request)
14996{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014997 hdd_adapter_t *pAdapter = NULL;
14998 hdd_context_t *pHddCtx = NULL;
14999 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015000 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015001 tCsrScanRequest scanRequest;
15002 tANI_U8 *channelList = NULL, i;
15003 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015004 int status;
15005 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015007 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015008 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015009 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015010 v_U8_t curr_session_id;
15011 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015012
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015013#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15014 struct net_device *dev = NULL;
15015 if (NULL == request)
15016 {
15017 hddLog(VOS_TRACE_LEVEL_ERROR,
15018 "%s: scan req param null", __func__);
15019 return -EINVAL;
15020 }
15021 dev = request->wdev->netdev;
15022#endif
15023
15024 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15025 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15026 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15027
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 ENTER();
15029
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15031 __func__, hdd_device_modetoString(pAdapter->device_mode),
15032 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015033
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015034 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015035 if (0 != status)
15036 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015037 return status;
15038 }
15039
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015040 if (NULL == pwextBuf)
15041 {
15042 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15043 __func__);
15044 return -EIO;
15045 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015046 cfg_param = pHddCtx->cfg_ini;
15047 pScanInfo = &pHddCtx->scan_info;
15048
Jeff Johnson295189b2012-06-20 16:38:30 -070015049#ifdef WLAN_BTAMP_FEATURE
15050 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015051 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015052 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015053 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 "%s: No scanning when AMP is on", __func__);
15055 return -EOPNOTSUPP;
15056 }
15057#endif
15058 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015059 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015060 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015061 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015062 "%s: Not scanning on device_mode = %s (%d)",
15063 __func__, hdd_device_modetoString(pAdapter->device_mode),
15064 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015065 return -EOPNOTSUPP;
15066 }
15067
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015068 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15069 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15070 return -EOPNOTSUPP;
15071 }
15072
Jeff Johnson295189b2012-06-20 16:38:30 -070015073 if (TRUE == pScanInfo->mScanPending)
15074 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015075 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15076 {
15077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15078 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015079 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015080 }
15081
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015082 // Don't allow scan if PNO scan is going on.
15083 if (pHddCtx->isPnoEnable)
15084 {
15085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15086 FL("pno scan in progress"));
15087 return -EBUSY;
15088 }
15089
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015090 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015091 //Channel and action frame is pending
15092 //Otherwise Cancel Remain On Channel and allow Scan
15093 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015094 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015095 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015097 return -EBUSY;
15098 }
15099
Jeff Johnson295189b2012-06-20 16:38:30 -070015100 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15101 {
15102 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015103 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015104 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015105 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015106 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15107 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015108 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015109 "%s: MAX TM Level Scan not allowed", __func__);
15110 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015111 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015112 }
15113 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15114
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015115 /* Check if scan is allowed at this point of time.
15116 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015117 if (TRUE == pHddCtx->btCoexModeSet)
15118 {
15119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15120 FL("BTCoex Mode operation in progress"));
15121 return -EBUSY;
15122 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015123 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015124 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015125
15126 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15127 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15128 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015129 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15130 pHddCtx->last_scan_reject_reason != curr_reason ||
15131 !pHddCtx->last_scan_reject_timestamp)
15132 {
15133 pHddCtx->last_scan_reject_session_id = curr_session_id;
15134 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015135 pHddCtx->last_scan_reject_timestamp =
15136 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015137 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015138 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015139 else
15140 {
15141 pHddCtx->scan_reject_cnt++;
15142
Abhishek Singhe4b12562017-06-20 16:53:39 +053015143 if ((pHddCtx->scan_reject_cnt >=
15144 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015145 vos_system_time_after(jiffies_to_msecs(jiffies),
15146 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015147 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015148 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15149 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15150 vos_system_time_after(jiffies_to_msecs(jiffies),
15151 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015152 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015153 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015154 if (pHddCtx->cfg_ini->enableFatalEvent)
15155 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15156 WLAN_LOG_INDICATOR_HOST_DRIVER,
15157 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15158 FALSE, FALSE);
15159 else
15160 {
15161 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015162 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015163 }
15164 }
15165 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015166 return -EBUSY;
15167 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015168 pHddCtx->last_scan_reject_timestamp = 0;
15169 pHddCtx->last_scan_reject_session_id = 0xFF;
15170 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015171 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015172
Jeff Johnson295189b2012-06-20 16:38:30 -070015173 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15174
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015175 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15176 * Becasue of this, driver is assuming that this is not wildcard scan and so
15177 * is not aging out the scan results.
15178 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015179 if ((request->ssids) && (request->n_ssids == 1) &&
15180 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015181 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015182 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015183
15184 if ((request->ssids) && (0 < request->n_ssids))
15185 {
15186 tCsrSSIDInfo *SsidInfo;
15187 int j;
15188 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15189 /* Allocate num_ssid tCsrSSIDInfo structure */
15190 SsidInfo = scanRequest.SSIDs.SSIDList =
15191 ( tCsrSSIDInfo *)vos_mem_malloc(
15192 request->n_ssids*sizeof(tCsrSSIDInfo));
15193
15194 if(NULL == scanRequest.SSIDs.SSIDList)
15195 {
15196 hddLog(VOS_TRACE_LEVEL_ERROR,
15197 "%s: memory alloc failed SSIDInfo buffer", __func__);
15198 return -ENOMEM;
15199 }
15200
15201 /* copy all the ssid's and their length */
15202 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15203 {
15204 /* get the ssid length */
15205 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15206 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15207 SsidInfo->SSID.length);
15208 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15209 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15210 j, SsidInfo->SSID.ssId);
15211 }
15212 /* set the scan type to active */
15213 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15214 }
15215 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015217 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15218 TRACE_CODE_HDD_CFG80211_SCAN,
15219 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015220 /* set the scan type to active */
15221 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015222 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015223 else
15224 {
15225 /*Set the scan type to default type, in this case it is ACTIVE*/
15226 scanRequest.scanType = pScanInfo->scan_mode;
15227 }
15228 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15229 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015230
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015231 csr_scan_request_assign_bssid(&scanRequest, request);
15232
Jeff Johnson295189b2012-06-20 16:38:30 -070015233 /* set BSSType to default type */
15234 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15235
15236 /*TODO: scan the requested channels only*/
15237
15238 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015239 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015240 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015241 hddLog(VOS_TRACE_LEVEL_WARN,
15242 "No of Scan Channels exceeded limit: %d", request->n_channels);
15243 request->n_channels = MAX_CHANNEL;
15244 }
15245
15246 hddLog(VOS_TRACE_LEVEL_INFO,
15247 "No of Scan Channels: %d", request->n_channels);
15248
15249
15250 if( request->n_channels )
15251 {
15252 char chList [(request->n_channels*5)+1];
15253 int len;
15254 channelList = vos_mem_malloc( request->n_channels );
15255 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015256 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015257 hddLog(VOS_TRACE_LEVEL_ERROR,
15258 "%s: memory alloc failed channelList", __func__);
15259 status = -ENOMEM;
15260 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015261 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015262
15263 for( i = 0, len = 0; i < request->n_channels ; i++ )
15264 {
15265 channelList[i] = request->channels[i]->hw_value;
15266 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15267 }
15268
Nirav Shah20ac06f2013-12-12 18:14:06 +053015269 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015270 "Channel-List: %s ", chList);
15271 }
c_hpothu53512302014-04-15 18:49:53 +053015272
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015273 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15274 scanRequest.ChannelInfo.ChannelList = channelList;
15275
15276 /* set requestType to full scan */
15277 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15278
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015279 /* if there is back to back scan happening in driver with in
15280 * nDeferScanTimeInterval interval driver should defer new scan request
15281 * and should provide last cached scan results instead of new channel list.
15282 * This rule is not applicable if scan is p2p scan.
15283 * This condition will work only in case when last request no of channels
15284 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015285 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015286 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015287 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015288
Sushant Kaushik86592172015-04-27 16:35:03 +053015289 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15290 /* if wps ie is NULL , then only defer scan */
15291 if ( pWpsIe == NULL &&
15292 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015293 {
15294 if ( pScanInfo->last_scan_timestamp !=0 &&
15295 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15296 {
15297 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15298 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15299 vos_mem_compare(pScanInfo->last_scan_channelList,
15300 channelList, pScanInfo->last_scan_numChannels))
15301 {
15302 hddLog(VOS_TRACE_LEVEL_WARN,
15303 " New and old station scan time differ is less then %u",
15304 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15305
15306 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015307 pAdapter);
15308
Agarwal Ashish57e84372014-12-05 18:26:53 +053015309 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015310 "Return old cached scan as all channels and no of channels are same");
15311
Agarwal Ashish57e84372014-12-05 18:26:53 +053015312 if (0 > ret)
15313 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015314
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015315 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015316
15317 status = eHAL_STATUS_SUCCESS;
15318 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015319 }
15320 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015321 }
15322
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015323 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15324 * search (Flush on both full scan and social scan but not on single
15325 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15326 */
15327
15328 /* Supplicant does single channel scan after 8-way handshake
15329 * and in that case driver shoudnt flush scan results. If
15330 * driver flushes the scan results here and unfortunately if
15331 * the AP doesnt respond to our probe req then association
15332 * fails which is not desired
15333 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015334 if ((request->n_ssids == 1)
15335 && (request->ssids != NULL)
15336 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15337 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015338
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015339 if( is_p2p_scan ||
15340 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015341 {
15342 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15343 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15344 pAdapter->sessionId );
15345 }
15346
15347 if( request->ie_len )
15348 {
15349 /* save this for future association (join requires this) */
15350 /*TODO: Array needs to be converted to dynamic allocation,
15351 * as multiple ie.s can be sent in cfg80211_scan_request structure
15352 * CR 597966
15353 */
15354 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15355 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15356 pScanInfo->scanAddIE.length = request->ie_len;
15357
15358 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15359 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15360 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015362 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015363 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015364 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15365 memcpy( pwextBuf->roamProfile.addIEScan,
15366 request->ie, request->ie_len);
15367 }
15368 else
15369 {
15370 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15371 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015372 }
15373
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015374 }
15375 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15376 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15377
15378 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15379 request->ie_len);
15380 if (pP2pIe != NULL)
15381 {
15382#ifdef WLAN_FEATURE_P2P_DEBUG
15383 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15384 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15385 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015386 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015387 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15388 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15389 "Go nego completed to Connection is started");
15390 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15391 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015392 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015393 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15394 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015395 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015396 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15397 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15398 "Disconnected state to Connection is started");
15399 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15400 "for 4way Handshake");
15401 }
15402#endif
15403
15404 /* no_cck will be set during p2p find to disable 11b rates */
15405 if(TRUE == request->no_cck)
15406 {
15407 hddLog(VOS_TRACE_LEVEL_INFO,
15408 "%s: This is a P2P Search", __func__);
15409 scanRequest.p2pSearch = 1;
15410
15411 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015412 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015413 /* set requestType to P2P Discovery */
15414 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15415 }
15416
15417 /*
15418 Skip Dfs Channel in case of P2P Search
15419 if it is set in ini file
15420 */
15421 if(cfg_param->skipDfsChnlInP2pSearch)
15422 {
15423 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015424 }
15425 else
15426 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015427 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015428 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015429
Agarwal Ashish4f616132013-12-30 23:32:50 +053015430 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015431 }
15432 }
15433
15434 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15435
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015436#ifdef FEATURE_WLAN_TDLS
15437 /* if tdls disagree scan right now, return immediately.
15438 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15439 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15440 */
15441 status = wlan_hdd_tdls_scan_callback (pAdapter,
15442 wiphy,
15443#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15444 dev,
15445#endif
15446 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015447 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015448 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015449 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15451 "scan rejected %d", __func__, status);
15452 else
15453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15454 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015455 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015456 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015457 }
15458#endif
15459
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015460 /* acquire the wakelock to avoid the apps suspend during the scan. To
15461 * address the following issues.
15462 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15463 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15464 * for long time, this result in apps running at full power for long time.
15465 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15466 * be stuck in full power because of resume BMPS
15467 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015468 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015469
Nirav Shah20ac06f2013-12-12 18:14:06 +053015470 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15471 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015472 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15473 scanRequest.requestType, scanRequest.scanType,
15474 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015475 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15476
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015477 if (pHddCtx->spoofMacAddr.isEnabled &&
15478 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015479 {
15480 hddLog(VOS_TRACE_LEVEL_INFO,
15481 "%s: MAC Spoofing enabled for current scan", __func__);
15482 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15483 * to fill TxBds for probe request during current scan
15484 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015485 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015486 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015487
15488 if(status != VOS_STATUS_SUCCESS)
15489 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015490 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015491 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015492#ifdef FEATURE_WLAN_TDLS
15493 wlan_hdd_tdls_scan_done_callback(pAdapter);
15494#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015495 goto free_mem;
15496 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015497 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015498 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015499 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015500 pAdapter->sessionId, &scanRequest, &scanId,
15501 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015502
Jeff Johnson295189b2012-06-20 16:38:30 -070015503 if (eHAL_STATUS_SUCCESS != status)
15504 {
15505 hddLog(VOS_TRACE_LEVEL_ERROR,
15506 "%s: sme_ScanRequest returned error %d", __func__, status);
15507 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015508 if(eHAL_STATUS_RESOURCES == status)
15509 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15511 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015512 status = -EBUSY;
15513 } else {
15514 status = -EIO;
15515 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015516 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015517
15518#ifdef FEATURE_WLAN_TDLS
15519 wlan_hdd_tdls_scan_done_callback(pAdapter);
15520#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015521 goto free_mem;
15522 }
15523
15524 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015525 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015526 pAdapter->request = request;
15527 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015528 pScanInfo->no_cck = request->no_cck;
15529 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15530 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15531 pHddCtx->scan_info.last_scan_channelList[i] =
15532 request->channels[i]->hw_value;
15533 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015534
15535 complete(&pScanInfo->scan_req_completion_event);
15536
15537free_mem:
15538 if( scanRequest.SSIDs.SSIDList )
15539 {
15540 vos_mem_free(scanRequest.SSIDs.SSIDList);
15541 }
15542
15543 if( channelList )
15544 vos_mem_free( channelList );
15545
15546 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 return status;
15548}
15549
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015550int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15551#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15552 struct net_device *dev,
15553#endif
15554 struct cfg80211_scan_request *request)
15555{
15556 int ret;
15557
15558 vos_ssr_protect(__func__);
15559 ret = __wlan_hdd_cfg80211_scan(wiphy,
15560#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15561 dev,
15562#endif
15563 request);
15564 vos_ssr_unprotect(__func__);
15565
15566 return ret;
15567}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015568
15569void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15570{
15571 v_U8_t iniDot11Mode =
15572 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15573 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15574
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015575 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15576 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015577 switch ( iniDot11Mode )
15578 {
15579 case eHDD_DOT11_MODE_AUTO:
15580 case eHDD_DOT11_MODE_11ac:
15581 case eHDD_DOT11_MODE_11ac_ONLY:
15582#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015583 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15584 sme_IsFeatureSupportedByFW(DOT11AC) )
15585 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15586 else
15587 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015588#else
15589 hddDot11Mode = eHDD_DOT11_MODE_11n;
15590#endif
15591 break;
15592 case eHDD_DOT11_MODE_11n:
15593 case eHDD_DOT11_MODE_11n_ONLY:
15594 hddDot11Mode = eHDD_DOT11_MODE_11n;
15595 break;
15596 default:
15597 hddDot11Mode = iniDot11Mode;
15598 break;
15599 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015600#ifdef WLAN_FEATURE_AP_HT40_24G
15601 if (operationChannel > SIR_11B_CHANNEL_END)
15602#endif
15603 {
15604 /* This call decides required channel bonding mode */
15605 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015606 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015607 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015608 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015609}
15610
Jeff Johnson295189b2012-06-20 16:38:30 -070015611/*
15612 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015613 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015614 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015615int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015616 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15617 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015618{
15619 int status = 0;
15620 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015621 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015622 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015623 v_U32_t roamId;
15624 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015625 eCsrAuthType RSNAuthType;
15626
15627 ENTER();
15628
15629 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015630 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015631 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015632
15633 status = wlan_hdd_validate_context(pHddCtx);
15634 if (status)
15635 {
Yue Mae36e3552014-03-05 17:06:20 -080015636 return status;
15637 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015638
Jeff Johnson295189b2012-06-20 16:38:30 -070015639 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15640 {
15641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15642 return -EINVAL;
15643 }
15644
Nitesh Shah9b066282017-06-06 18:05:52 +053015645 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15646
Jeff Johnson295189b2012-06-20 16:38:30 -070015647 pRoamProfile = &pWextState->roamProfile;
15648
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015649 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015650 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015651 hdd_station_ctx_t *pHddStaCtx;
15652 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015653 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015654
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015655 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15656
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015657 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015658 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15659 {
15660 /*QoS not enabled in cfg file*/
15661 pRoamProfile->uapsd_mask = 0;
15662 }
15663 else
15664 {
15665 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015666 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015667 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15668 }
15669
15670 pRoamProfile->SSIDs.numOfSSIDs = 1;
15671 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15672 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015673 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015674 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15675 ssid, ssid_len);
15676
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015677 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15678 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15679
Jeff Johnson295189b2012-06-20 16:38:30 -070015680 if (bssid)
15681 {
15682 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015683 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015684 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015685 /* Save BSSID in seperate variable as well, as RoamProfile
15686 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015687 case of join failure we should send valid BSSID to supplicant
15688 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015689 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015690 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015691
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015693 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015694 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015695 /* Store bssid_hint to use in the scan filter. */
15696 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15697 WNI_CFG_BSSID_LEN);
15698 /*
15699 * Save BSSID in seperate variable as well, as RoamProfile
15700 * BSSID is getting zeroed out in the association process. And in
15701 * case of join failure we should send valid BSSID to supplicant
15702 */
15703 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15704 WNI_CFG_BSSID_LEN);
15705 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15706 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015707 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015708
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015709
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015710 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15711 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015712 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15713 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015714 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 /*set gen ie*/
15716 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15717 /*set auth*/
15718 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15719 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015720#ifdef FEATURE_WLAN_WAPI
15721 if (pAdapter->wapi_info.nWapiMode)
15722 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015723 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015724 switch (pAdapter->wapi_info.wapiAuthMode)
15725 {
15726 case WAPI_AUTH_MODE_PSK:
15727 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015728 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015729 pAdapter->wapi_info.wapiAuthMode);
15730 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15731 break;
15732 }
15733 case WAPI_AUTH_MODE_CERT:
15734 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015735 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015736 pAdapter->wapi_info.wapiAuthMode);
15737 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15738 break;
15739 }
15740 } // End of switch
15741 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15742 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15743 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015744 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015745 pRoamProfile->AuthType.numEntries = 1;
15746 pRoamProfile->EncryptionType.numEntries = 1;
15747 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15748 pRoamProfile->mcEncryptionType.numEntries = 1;
15749 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15750 }
15751 }
15752#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015753#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015754 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015755 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15756 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15757 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015758 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15759 sizeof (tSirGtkOffloadParams));
15760 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015761 }
15762#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015763 pRoamProfile->csrPersona = pAdapter->device_mode;
15764
Jeff Johnson32d95a32012-09-10 13:15:23 -070015765 if( operatingChannel )
15766 {
15767 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15768 pRoamProfile->ChannelInfo.numOfChannels = 1;
15769 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015770 else
15771 {
15772 pRoamProfile->ChannelInfo.ChannelList = NULL;
15773 pRoamProfile->ChannelInfo.numOfChannels = 0;
15774 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015775 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15776 {
15777 hdd_select_cbmode(pAdapter,operatingChannel);
15778 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015779
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015780 /*
15781 * Change conn_state to connecting before sme_RoamConnect(),
15782 * because sme_RoamConnect() has a direct path to call
15783 * hdd_smeRoamCallback(), which will change the conn_state
15784 * If direct path, conn_state will be accordingly changed
15785 * to NotConnected or Associated by either
15786 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15787 * in sme_RoamCallback()
15788 * if sme_RomConnect is to be queued,
15789 * Connecting state will remain until it is completed.
15790 * If connection state is not changed,
15791 * connection state will remain in eConnectionState_NotConnected state.
15792 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15793 * if conn state is eConnectionState_NotConnected.
15794 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15795 * informed of connect result indication which is an issue.
15796 */
15797
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015798 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15799 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015800 {
15801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015802 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015803 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15804 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015805 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
15806 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015807 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015808
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015809 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015810 pAdapter->sessionId, pRoamProfile, &roamId);
15811
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015812 if ((eHAL_STATUS_SUCCESS != status) &&
15813 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15814 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015815
15816 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015817 hddLog(VOS_TRACE_LEVEL_ERROR,
15818 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15819 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015820 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015821 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015822 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015823 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015824
15825 pRoamProfile->ChannelInfo.ChannelList = NULL;
15826 pRoamProfile->ChannelInfo.numOfChannels = 0;
15827
Jeff Johnson295189b2012-06-20 16:38:30 -070015828 }
15829 else
15830 {
15831 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15832 return -EINVAL;
15833 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015834 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015835 return status;
15836}
15837
15838/*
15839 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15840 * This function is used to set the authentication type (OPEN/SHARED).
15841 *
15842 */
15843static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15844 enum nl80211_auth_type auth_type)
15845{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015846 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015847 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15848
15849 ENTER();
15850
15851 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015852 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015853 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015854 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015855 hddLog(VOS_TRACE_LEVEL_INFO,
15856 "%s: set authentication type to AUTOSWITCH", __func__);
15857 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15858 break;
15859
15860 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015861#ifdef WLAN_FEATURE_VOWIFI_11R
15862 case NL80211_AUTHTYPE_FT:
15863#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015864 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015865 "%s: set authentication type to OPEN", __func__);
15866 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15867 break;
15868
15869 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015870 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015871 "%s: set authentication type to SHARED", __func__);
15872 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15873 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015874#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015875 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015876 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015877 "%s: set authentication type to CCKM WPA", __func__);
15878 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15879 break;
15880#endif
15881
15882
15883 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015884 hddLog(VOS_TRACE_LEVEL_ERROR,
15885 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015886 auth_type);
15887 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15888 return -EINVAL;
15889 }
15890
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015891 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015892 pHddStaCtx->conn_info.authType;
15893 return 0;
15894}
15895
15896/*
15897 * FUNCTION: wlan_hdd_set_akm_suite
15898 * This function is used to set the key mgmt type(PSK/8021x).
15899 *
15900 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015901static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015902 u32 key_mgmt
15903 )
15904{
15905 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15906 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015907 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015908#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015909#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015910#endif
15911#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015912#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015913#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015914 /*set key mgmt type*/
15915 switch(key_mgmt)
15916 {
15917 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015918 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015919#ifdef WLAN_FEATURE_VOWIFI_11R
15920 case WLAN_AKM_SUITE_FT_PSK:
15921#endif
15922 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015923 __func__);
15924 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15925 break;
15926
15927 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015928 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015929#ifdef WLAN_FEATURE_VOWIFI_11R
15930 case WLAN_AKM_SUITE_FT_8021X:
15931#endif
15932 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015933 __func__);
15934 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15935 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015936#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015937#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15938#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15939 case WLAN_AKM_SUITE_CCKM:
15940 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15941 __func__);
15942 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15943 break;
15944#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015945#ifndef WLAN_AKM_SUITE_OSEN
15946#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15947 case WLAN_AKM_SUITE_OSEN:
15948 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15949 __func__);
15950 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15951 break;
15952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015953
15954 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015955 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015956 __func__, key_mgmt);
15957 return -EINVAL;
15958
15959 }
15960 return 0;
15961}
15962
15963/*
15964 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015965 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015966 * (NONE/WEP40/WEP104/TKIP/CCMP).
15967 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015968static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15969 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015970 bool ucast
15971 )
15972{
15973 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015974 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15976
15977 ENTER();
15978
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015979 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015980 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015981 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015982 __func__, cipher);
15983 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15984 }
15985 else
15986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015987
Jeff Johnson295189b2012-06-20 16:38:30 -070015988 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015989 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 {
15991 case IW_AUTH_CIPHER_NONE:
15992 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15993 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015994
Jeff Johnson295189b2012-06-20 16:38:30 -070015995 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015996 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015997 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015998
Jeff Johnson295189b2012-06-20 16:38:30 -070015999 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016000 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016001 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016002
Jeff Johnson295189b2012-06-20 16:38:30 -070016003 case WLAN_CIPHER_SUITE_TKIP:
16004 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16005 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016006
Jeff Johnson295189b2012-06-20 16:38:30 -070016007 case WLAN_CIPHER_SUITE_CCMP:
16008 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16009 break;
16010#ifdef FEATURE_WLAN_WAPI
16011 case WLAN_CIPHER_SUITE_SMS4:
16012 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16013 break;
16014#endif
16015
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016016#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016017 case WLAN_CIPHER_SUITE_KRK:
16018 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16019 break;
16020#endif
16021 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016022 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 __func__, cipher);
16024 return -EOPNOTSUPP;
16025 }
16026 }
16027
16028 if (ucast)
16029 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016031 __func__, encryptionType);
16032 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16033 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016034 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016035 encryptionType;
16036 }
16037 else
16038 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016039 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016040 __func__, encryptionType);
16041 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16042 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16043 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16044 }
16045
16046 return 0;
16047}
16048
16049
16050/*
16051 * FUNCTION: wlan_hdd_cfg80211_set_ie
16052 * This function is used to parse WPA/RSN IE's.
16053 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016054int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16056 const u8 *ie,
16057#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016058 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016059#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 size_t ie_len
16061 )
16062{
16063 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16065 const u8 *genie = ie;
16066#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016067 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016068#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016069 v_U16_t remLen = ie_len;
16070#ifdef FEATURE_WLAN_WAPI
16071 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16072 u16 *tmp;
16073 v_U16_t akmsuiteCount;
16074 int *akmlist;
16075#endif
16076 ENTER();
16077
16078 /* clear previous assocAddIE */
16079 pWextState->assocAddIE.length = 0;
16080 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016081 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016082
16083 while (remLen >= 2)
16084 {
16085 v_U16_t eLen = 0;
16086 v_U8_t elementId;
16087 elementId = *genie++;
16088 eLen = *genie++;
16089 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016090
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016091 /* Sanity check on eLen */
16092 if (eLen > remLen) {
16093 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16094 __func__, eLen, elementId);
16095 VOS_ASSERT(0);
16096 return -EINVAL;
16097 }
16098
Arif Hussain6d2a3322013-11-17 19:50:10 -080016099 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016101
16102 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016104 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016105 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 -070016106 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016107 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016108 "%s: Invalid WPA IE", __func__);
16109 return -EINVAL;
16110 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016111 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 {
16113 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016114 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016115 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016116
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016117 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016118 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016119 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16120 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 VOS_ASSERT(0);
16122 return -ENOMEM;
16123 }
16124 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16125 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16126 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016127
Jeff Johnson295189b2012-06-20 16:38:30 -070016128 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16129 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16130 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16131 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016132 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16133 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016134 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16136 __func__, eLen);
16137 VOS_ASSERT(0);
16138 return -EINVAL;
16139 }
16140
Jeff Johnson295189b2012-06-20 16:38:30 -070016141 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16142 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16143 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16144 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16145 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16146 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016147 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016148 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 {
16150 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016151 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016152 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016153
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016154 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016156 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16157 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016158 VOS_ASSERT(0);
16159 return -ENOMEM;
16160 }
16161 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16162 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16163 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016164
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16166 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16167 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016168#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016169 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16170 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 /*Consider WFD IE, only for P2P Client */
16172 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16173 {
16174 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016175 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016177
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016178 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016179 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016180 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16181 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016182 VOS_ASSERT(0);
16183 return -ENOMEM;
16184 }
16185 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16186 // WPS IE + P2P IE + WFD IE
16187 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16188 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016189
Jeff Johnson295189b2012-06-20 16:38:30 -070016190 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16191 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16192 }
16193#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016194 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016195 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016196 HS20_OUI_TYPE_SIZE)) )
16197 {
16198 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016199 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016200 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016201
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016202 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016203 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016204 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16205 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016206 VOS_ASSERT(0);
16207 return -ENOMEM;
16208 }
16209 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16210 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016211
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016212 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16213 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16214 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016215 /* Appending OSEN Information Element in Assiciation Request */
16216 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16217 OSEN_OUI_TYPE_SIZE)) )
16218 {
16219 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16220 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16221 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016222
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016223 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016224 {
16225 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16226 "Need bigger buffer space");
16227 VOS_ASSERT(0);
16228 return -ENOMEM;
16229 }
16230 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16231 pWextState->assocAddIE.length += eLen + 2;
16232
16233 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16234 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16235 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16236 }
16237
Abhishek Singh4322e622015-06-10 15:42:54 +053016238 /* Update only for WPA IE */
16239 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16240 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016241
16242 /* populating as ADDIE in beacon frames */
16243 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016244 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016245 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16246 {
16247 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16248 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16249 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16250 {
16251 hddLog(LOGE,
16252 "Coldn't pass "
16253 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16254 }
16255 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16256 else
16257 hddLog(LOGE,
16258 "Could not pass on "
16259 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16260
16261 /* IBSS mode doesn't contain params->proberesp_ies still
16262 beaconIE's need to be populated in probe response frames */
16263 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16264 {
16265 u16 rem_probe_resp_ie_len = eLen + 2;
16266 u8 probe_rsp_ie_len[3] = {0};
16267 u8 counter = 0;
16268
16269 /* Check Probe Resp Length if it is greater then 255 then
16270 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16271 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16272 not able Store More then 255 bytes into One Variable */
16273
16274 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16275 {
16276 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16277 {
16278 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16279 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16280 }
16281 else
16282 {
16283 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16284 rem_probe_resp_ie_len = 0;
16285 }
16286 }
16287
16288 rem_probe_resp_ie_len = 0;
16289
16290 if (probe_rsp_ie_len[0] > 0)
16291 {
16292 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16293 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16294 (tANI_U8*)(genie - 2),
16295 probe_rsp_ie_len[0], NULL,
16296 eANI_BOOLEAN_FALSE)
16297 == eHAL_STATUS_FAILURE)
16298 {
16299 hddLog(LOGE,
16300 "Could not pass"
16301 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16302 }
16303 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16304 }
16305
16306 if (probe_rsp_ie_len[1] > 0)
16307 {
16308 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16309 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16310 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16311 probe_rsp_ie_len[1], NULL,
16312 eANI_BOOLEAN_FALSE)
16313 == eHAL_STATUS_FAILURE)
16314 {
16315 hddLog(LOGE,
16316 "Could not pass"
16317 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16318 }
16319 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16320 }
16321
16322 if (probe_rsp_ie_len[2] > 0)
16323 {
16324 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16325 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16326 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16327 probe_rsp_ie_len[2], NULL,
16328 eANI_BOOLEAN_FALSE)
16329 == eHAL_STATUS_FAILURE)
16330 {
16331 hddLog(LOGE,
16332 "Could not pass"
16333 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16334 }
16335 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16336 }
16337
16338 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16339 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16340 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16341 {
16342 hddLog(LOGE,
16343 "Could not pass"
16344 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16345 }
16346 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016347 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016348 break;
16349 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016350 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16351 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16352 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16353 VOS_ASSERT(0);
16354 return -EINVAL;
16355 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016356 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16357 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16358 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16359 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16360 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16361 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016362
Abhishek Singhb16f3562016-01-20 11:08:32 +053016363 /* Appending extended capabilities with Interworking or
16364 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016365 *
16366 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016367 * interworkingService or bsstransition bit is set to 1.
16368 * Driver is only interested in interworkingService and
16369 * bsstransition capability from supplicant.
16370 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016371 * required from supplicat, it needs to be handled while
16372 * sending Assoc Req in LIM.
16373 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016374 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016375 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016376 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016377 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016378 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016379
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016380 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016381 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016382 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16383 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016384 VOS_ASSERT(0);
16385 return -ENOMEM;
16386 }
16387 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16388 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016389
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016390 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16391 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16392 break;
16393 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016394#ifdef FEATURE_WLAN_WAPI
16395 case WLAN_EID_WAPI:
16396 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016397 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016398 pAdapter->wapi_info.nWapiMode);
16399 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016400 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016401 akmsuiteCount = WPA_GET_LE16(tmp);
16402 tmp = tmp + 1;
16403 akmlist = (int *)(tmp);
16404 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16405 {
16406 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16407 }
16408 else
16409 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016410 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016411 VOS_ASSERT(0);
16412 return -EINVAL;
16413 }
16414
16415 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16416 {
16417 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016418 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016419 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016420 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016421 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016422 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016423 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016424 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016425 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16426 }
16427 break;
16428#endif
16429 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016430 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016432 /* when Unknown IE is received we should break and continue
16433 * to the next IE in the buffer instead we were returning
16434 * so changing this to break */
16435 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016436 }
16437 genie += eLen;
16438 remLen -= eLen;
16439 }
16440 EXIT();
16441 return 0;
16442}
16443
16444/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016445 * FUNCTION: hdd_isWPAIEPresent
16446 * Parse the received IE to find the WPA IE
16447 *
16448 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016449static bool hdd_isWPAIEPresent(
16450#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16451 const u8 *ie,
16452#else
16453 u8 *ie,
16454#endif
16455 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016456{
16457 v_U8_t eLen = 0;
16458 v_U16_t remLen = ie_len;
16459 v_U8_t elementId = 0;
16460
16461 while (remLen >= 2)
16462 {
16463 elementId = *ie++;
16464 eLen = *ie++;
16465 remLen -= 2;
16466 if (eLen > remLen)
16467 {
16468 hddLog(VOS_TRACE_LEVEL_ERROR,
16469 "%s: IE length is wrong %d", __func__, eLen);
16470 return FALSE;
16471 }
16472 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16473 {
16474 /* OUI - 0x00 0X50 0XF2
16475 WPA Information Element - 0x01
16476 WPA version - 0x01*/
16477 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16478 return TRUE;
16479 }
16480 ie += eLen;
16481 remLen -= eLen;
16482 }
16483 return FALSE;
16484}
16485
16486/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016487 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016488 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016489 * parameters during connect operation.
16490 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016491int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016492 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016493 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016494{
16495 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016496 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016497 ENTER();
16498
16499 /*set wpa version*/
16500 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16501
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016502 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016503 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016504 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016505 {
16506 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16507 }
16508 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16509 {
16510 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16511 }
16512 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016513
16514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016515 pWextState->wpaVersion);
16516
16517 /*set authentication type*/
16518 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16519
16520 if (0 > status)
16521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016522 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016523 "%s: failed to set authentication type ", __func__);
16524 return status;
16525 }
16526
16527 /*set key mgmt type*/
16528 if (req->crypto.n_akm_suites)
16529 {
16530 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16531 if (0 > status)
16532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016534 __func__);
16535 return status;
16536 }
16537 }
16538
16539 /*set pairwise cipher type*/
16540 if (req->crypto.n_ciphers_pairwise)
16541 {
16542 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16543 req->crypto.ciphers_pairwise[0], true);
16544 if (0 > status)
16545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016546 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016547 "%s: failed to set unicast cipher type", __func__);
16548 return status;
16549 }
16550 }
16551 else
16552 {
16553 /*Reset previous cipher suite to none*/
16554 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16555 if (0 > status)
16556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016557 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016558 "%s: failed to set unicast cipher type", __func__);
16559 return status;
16560 }
16561 }
16562
16563 /*set group cipher type*/
16564 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16565 false);
16566
16567 if (0 > status)
16568 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016570 __func__);
16571 return status;
16572 }
16573
Chet Lanctot186b5732013-03-18 10:26:30 -070016574#ifdef WLAN_FEATURE_11W
16575 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16576#endif
16577
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16579 if (req->ie_len)
16580 {
16581 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16582 if ( 0 > status)
16583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016585 __func__);
16586 return status;
16587 }
16588 }
16589
16590 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016591 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016592 {
16593 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16594 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16595 )
16596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016597 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016598 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016601 __func__);
16602 return -EOPNOTSUPP;
16603 }
16604 else
16605 {
16606 u8 key_len = req->key_len;
16607 u8 key_idx = req->key_idx;
16608
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016609 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016610 && (CSR_MAX_NUM_KEY > key_idx)
16611 )
16612 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016613 hddLog(VOS_TRACE_LEVEL_INFO,
16614 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016615 __func__, key_idx, key_len);
16616 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016617 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016618 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016619 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016620 (u8)key_len;
16621 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16622 }
16623 }
16624 }
16625 }
16626
16627 return status;
16628}
16629
16630/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016631 * FUNCTION: wlan_hdd_try_disconnect
16632 * This function is used to disconnect from previous
16633 * connection
16634 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016635int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016636{
16637 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016638 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016639 hdd_station_ctx_t *pHddStaCtx;
16640 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016641 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016642
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016643 ret = wlan_hdd_validate_context(pHddCtx);
16644 if (0 != ret)
16645 {
16646 return ret;
16647 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016648 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16649
16650 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16651
16652 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16653 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016654 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016655 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16656 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016657 /* Indicate disconnect to SME so that in-progress connection or preauth
16658 * can be aborted
16659 */
16660 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16661 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016662 spin_lock_bh(&pAdapter->lock_for_active_session);
16663 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16664 {
16665 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16666 }
16667 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016668 hdd_connSetConnectionState(pHddStaCtx,
16669 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016670 /* Issue disconnect to CSR */
16671 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016672 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016673 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016674 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16675 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16676 hddLog(LOG1,
16677 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16678 } else if ( 0 != status ) {
16679 hddLog(LOGE,
16680 FL("csrRoamDisconnect failure, returned %d"),
16681 (int)status );
16682 result = -EINVAL;
16683 goto disconnected;
16684 }
16685 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016686 &pAdapter->disconnect_comp_var,
16687 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016688 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16689 hddLog(LOGE,
16690 "%s: Failed to disconnect, timed out", __func__);
16691 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016692 }
16693 }
16694 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16695 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016696 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016697 &pAdapter->disconnect_comp_var,
16698 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016699 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016700 {
16701 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016702 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016703 }
16704 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016705disconnected:
16706 hddLog(LOG1,
16707 FL("Set HDD connState to eConnectionState_NotConnected"));
16708 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16709 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016710}
16711
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016712/**
16713 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16714 * @adapter: Pointer to the HDD adapter
16715 * @req: Pointer to the structure cfg_connect_params receieved from user space
16716 *
16717 * This function will start reassociation if bssid hint, channel hint and
16718 * previous bssid parameters are present in the connect request
16719 *
16720 * Return: success if reassociation is happening
16721 * Error code if reassociation is not permitted or not happening
16722 */
16723#ifdef CFG80211_CONNECT_PREV_BSSID
16724static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16725 struct cfg80211_connect_params *req)
16726{
16727 int status = -EPERM;
16728 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16729 hddLog(VOS_TRACE_LEVEL_INFO,
16730 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16731 req->channel_hint->hw_value,
16732 MAC_ADDR_ARRAY(req->bssid_hint));
16733 status = hdd_reassoc(adapter, req->bssid_hint,
16734 req->channel_hint->hw_value,
16735 CONNECT_CMD_USERSPACE);
16736 }
16737 return status;
16738}
16739#else
16740static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16741 struct cfg80211_connect_params *req)
16742{
16743 return -EPERM;
16744}
16745#endif
16746
Abhishek Singhe3beee22017-07-31 15:35:40 +053016747/**
16748 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16749 * connect in HT20 mode
16750 * @hdd_ctx: hdd context
16751 * @adapter: Pointer to the HDD adapter
16752 * @req: Pointer to the structure cfg_connect_params receieved from user space
16753 *
16754 * This function will check if supplicant has indicated to to connect in HT20
16755 * mode. this is currently applicable only for 2.4Ghz mode only.
16756 * if feature is enabled and supplicant indicate HT20 set
16757 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16758 *
16759 * Return: void
16760 */
16761#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16762static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16763 hdd_adapter_t *adapter,
16764 struct cfg80211_connect_params *req)
16765{
16766 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16767 tCsrRoamProfile *roam_profile;
16768
16769 roam_profile = &wext_state->roamProfile;
16770 roam_profile->force_24ghz_in_ht20 = false;
16771 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16772 !(req->ht_capa.cap_info &
16773 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16774 roam_profile->force_24ghz_in_ht20 = true;
16775
16776 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16777 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16778}
16779#else
16780static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16781 hdd_adapter_t *adapter,
16782 struct cfg80211_connect_params *req)
16783{
16784 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16785 tCsrRoamProfile *roam_profile;
16786
16787 roam_profile = &wext_state->roamProfile;
16788 roam_profile->force_24ghz_in_ht20 = false;
16789}
16790#endif
16791
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016792/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016793 * FUNCTION: __wlan_hdd_cfg80211_connect
16794 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016795 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016796static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016797 struct net_device *ndev,
16798 struct cfg80211_connect_params *req
16799 )
16800{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016801 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016802 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16804 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016805 const u8 *bssid_hint = req->bssid_hint;
16806#else
16807 const u8 *bssid_hint = NULL;
16808#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016809 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016810 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016811 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016812
16813 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016814
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16816 TRACE_CODE_HDD_CFG80211_CONNECT,
16817 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016818 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016819 "%s: device_mode = %s (%d)", __func__,
16820 hdd_device_modetoString(pAdapter->device_mode),
16821 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016822
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016824 if (!pHddCtx)
16825 {
16826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16827 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016828 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016829 }
16830
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016831 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016832 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016834 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016835 }
16836
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016837 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16838 return -EINVAL;
16839
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016840 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16841 if (0 == status)
16842 return status;
16843
Agarwal Ashish51325b52014-06-16 16:50:49 +053016844
Jeff Johnson295189b2012-06-20 16:38:30 -070016845#ifdef WLAN_BTAMP_FEATURE
16846 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016847 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016849 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016850 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016851 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016852 }
16853#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016854
16855 //If Device Mode is Station Concurrent Sessions Exit BMps
16856 //P2P Mode will be taken care in Open/close adapter
16857 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016858 (vos_concurrent_open_sessions_running())) {
16859 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16860 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016861 }
16862
16863 /*Try disconnecting if already in connected state*/
16864 status = wlan_hdd_try_disconnect(pAdapter);
16865 if ( 0 > status)
16866 {
16867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16868 " connection"));
16869 return -EALREADY;
16870 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016871 /* Check for max concurrent connections after doing disconnect if any*/
16872 if (vos_max_concurrent_connections_reached()) {
16873 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16874 return -ECONNREFUSED;
16875 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016876
Jeff Johnson295189b2012-06-20 16:38:30 -070016877 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016878 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016879
16880 if ( 0 > status)
16881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016883 __func__);
16884 return status;
16885 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016886
16887 if (pHddCtx->spoofMacAddr.isEnabled)
16888 {
16889 hddLog(VOS_TRACE_LEVEL_INFO,
16890 "%s: MAC Spoofing enabled ", __func__);
16891 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16892 * to fill TxBds for probe request during SSID scan which may happen
16893 * as part of connect command
16894 */
16895 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16896 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16897 if (status != VOS_STATUS_SUCCESS)
16898 return -ECONNREFUSED;
16899 }
16900
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016901 if (req->channel)
16902 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016903 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016904 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016905
16906 /* Abort if any scan is going on */
16907 status = wlan_hdd_scan_abort(pAdapter);
16908 if (0 != status)
16909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16910
Abhishek Singhe3beee22017-07-31 15:35:40 +053016911 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16912
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016913 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16914 req->ssid_len, req->bssid,
16915 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016916
Sushant Kaushikd7083982015-03-18 14:33:24 +053016917 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016918 {
16919 //ReEnable BMPS if disabled
16920 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16921 (NULL != pHddCtx))
16922 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016923 if (pHddCtx->hdd_wlan_suspended)
16924 {
16925 hdd_set_pwrparams(pHddCtx);
16926 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016927 //ReEnable Bmps and Imps back
16928 hdd_enable_bmps_imps(pHddCtx);
16929 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016931 return status;
16932 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016933 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016934 EXIT();
16935 return status;
16936}
16937
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016938static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16939 struct net_device *ndev,
16940 struct cfg80211_connect_params *req)
16941{
16942 int ret;
16943 vos_ssr_protect(__func__);
16944 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16945 vos_ssr_unprotect(__func__);
16946
16947 return ret;
16948}
Jeff Johnson295189b2012-06-20 16:38:30 -070016949
16950/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016951 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016952 * This function is used to issue a disconnect request to SME
16953 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016954static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016955 struct net_device *dev,
16956 u16 reason
16957 )
16958{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016960 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016961 tCsrRoamProfile *pRoamProfile;
16962 hdd_station_ctx_t *pHddStaCtx;
16963 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016964#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016965 tANI_U8 staIdx;
16966#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016967
Jeff Johnson295189b2012-06-20 16:38:30 -070016968 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016969
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016970 if (!pAdapter) {
16971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16972 return -EINVAL;
16973 }
16974
16975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16976 if (!pHddStaCtx) {
16977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16978 return -EINVAL;
16979 }
16980
16981 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16982 status = wlan_hdd_validate_context(pHddCtx);
16983 if (0 != status)
16984 {
16985 return status;
16986 }
16987
16988 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16989
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016990 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16991 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16992 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016993 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16994 __func__, hdd_device_modetoString(pAdapter->device_mode),
16995 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016996
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016997 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16998 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016999
Jeff Johnson295189b2012-06-20 16:38:30 -070017000 if (NULL != pRoamProfile)
17001 {
17002 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017003 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17004 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017006 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017007 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017008 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017009 switch(reason)
17010 {
17011 case WLAN_REASON_MIC_FAILURE:
17012 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17013 break;
17014
17015 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17016 case WLAN_REASON_DISASSOC_AP_BUSY:
17017 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17018 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17019 break;
17020
17021 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17022 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017023 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017024 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17025 break;
17026
Jeff Johnson295189b2012-06-20 16:38:30 -070017027 default:
17028 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17029 break;
17030 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017031 pScanInfo = &pHddCtx->scan_info;
17032 if (pScanInfo->mScanPending)
17033 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017034 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017035 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017036 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017037 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017038 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017039 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017040#ifdef FEATURE_WLAN_TDLS
17041 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017042 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017043 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017044 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17045 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017046 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017047 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017048 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017050 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017051 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017052 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017053 status = sme_DeleteTdlsPeerSta(
17054 WLAN_HDD_GET_HAL_CTX(pAdapter),
17055 pAdapter->sessionId,
17056 mac);
17057 if (status != eHAL_STATUS_SUCCESS) {
17058 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17059 return -EPERM;
17060 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017061 }
17062 }
17063#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017064
17065 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17066 reasonCode,
17067 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017068 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17069 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017070 {
17071 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017072 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017073 __func__, (int)status );
17074 return -EINVAL;
17075 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017076 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017077 else
17078 {
17079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17080 "called while in %d state", __func__,
17081 pHddStaCtx->conn_info.connState);
17082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017083 }
17084 else
17085 {
17086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17087 }
17088
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017089 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017090 return status;
17091}
17092
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017093static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17094 struct net_device *dev,
17095 u16 reason
17096 )
17097{
17098 int ret;
17099 vos_ssr_protect(__func__);
17100 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17101 vos_ssr_unprotect(__func__);
17102
17103 return ret;
17104}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017105
Jeff Johnson295189b2012-06-20 16:38:30 -070017106/*
17107 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017108 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017109 * settings in IBSS mode.
17110 */
17111static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017112 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017113 struct cfg80211_ibss_params *params
17114 )
17115{
17116 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017117 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017118 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17119 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017120
Jeff Johnson295189b2012-06-20 16:38:30 -070017121 ENTER();
17122
17123 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017124 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017125
17126 if (params->ie_len && ( NULL != params->ie) )
17127 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017128 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17129 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017130 {
17131 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17132 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17133 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017134 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017135 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017136 tDot11fIEWPA dot11WPAIE;
17137 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017138 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017139
Wilson Yang00256342013-10-10 23:13:38 -070017140 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017141 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17142 params->ie_len, DOT11F_EID_WPA);
17143 if ( NULL != ie )
17144 {
17145 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17146 // Unpack the WPA IE
17147 //Skip past the EID byte and length byte - and four byte WiFi OUI
17148 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
17149 &ie[2+4],
17150 ie[1] - 4,
17151 &dot11WPAIE);
17152 /*Extract the multicast cipher, the encType for unicast
17153 cipher for wpa-none is none*/
17154 encryptionType =
17155 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17156 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017157 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017158
Jeff Johnson295189b2012-06-20 16:38:30 -070017159 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17160
17161 if (0 > status)
17162 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017164 __func__);
17165 return status;
17166 }
17167 }
17168
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017169 pWextState->roamProfile.AuthType.authType[0] =
17170 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017171 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017172 if (params->privacy)
17173 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174 /* Security enabled IBSS, At this time there is no information available
17175 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017176 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017177 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017178 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017179 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017180 *enable privacy bit in beacons */
17181
17182 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17183 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017184 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17185 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17187 pWextState->roamProfile.EncryptionType.numEntries = 1;
17188 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017189 return status;
17190}
17191
17192/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017193 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017194 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017195 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017196static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017197 struct net_device *dev,
17198 struct cfg80211_ibss_params *params
17199 )
17200{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017201 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017202 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17203 tCsrRoamProfile *pRoamProfile;
17204 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017205 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017207 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017208
17209 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017210
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017211 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17212 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17213 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017214 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017215 "%s: device_mode = %s (%d)", __func__,
17216 hdd_device_modetoString(pAdapter->device_mode),
17217 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017218
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017219 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017220 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017221 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017222 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017223 }
17224
17225 if (NULL == pWextState)
17226 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017227 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017228 __func__);
17229 return -EIO;
17230 }
17231
Agarwal Ashish51325b52014-06-16 16:50:49 +053017232 if (vos_max_concurrent_connections_reached()) {
17233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17234 return -ECONNREFUSED;
17235 }
17236
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017237 /*Try disconnecting if already in connected state*/
17238 status = wlan_hdd_try_disconnect(pAdapter);
17239 if ( 0 > status)
17240 {
17241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17242 " IBSS connection"));
17243 return -EALREADY;
17244 }
17245
Jeff Johnson295189b2012-06-20 16:38:30 -070017246 pRoamProfile = &pWextState->roamProfile;
17247
17248 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17249 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017250 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017251 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017252 return -EINVAL;
17253 }
17254
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017255 /* BSSID is provided by upper layers hence no need to AUTO generate */
17256 if (NULL != params->bssid) {
17257 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17258 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17259 hddLog (VOS_TRACE_LEVEL_ERROR,
17260 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17261 return -EIO;
17262 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017263 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017264 }
krunal sonie9002db2013-11-25 14:24:17 -080017265 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17266 {
17267 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17268 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17269 {
17270 hddLog (VOS_TRACE_LEVEL_ERROR,
17271 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17272 return -EIO;
17273 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017274
17275 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017276 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017277 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017278 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017279
Jeff Johnson295189b2012-06-20 16:38:30 -070017280 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017281 if (NULL !=
17282#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17283 params->chandef.chan)
17284#else
17285 params->channel)
17286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017287 {
17288 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017289 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17290 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17291 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17292 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017293
17294 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017295 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017296 ieee80211_frequency_to_channel(
17297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17298 params->chandef.chan->center_freq);
17299#else
17300 params->channel->center_freq);
17301#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017302
17303 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17304 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017305 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17307 __func__);
17308 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017309 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017310
17311 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017312 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017313 if (channelNum == validChan[indx])
17314 {
17315 break;
17316 }
17317 }
17318 if (indx >= numChans)
17319 {
17320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017321 __func__, channelNum);
17322 return -EINVAL;
17323 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017324 /* Set the Operational Channel */
17325 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17326 channelNum);
17327 pRoamProfile->ChannelInfo.numOfChannels = 1;
17328 pHddStaCtx->conn_info.operationChannel = channelNum;
17329 pRoamProfile->ChannelInfo.ChannelList =
17330 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017331 }
17332
17333 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017334 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017335 if (status < 0)
17336 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017338 __func__);
17339 return status;
17340 }
17341
17342 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017343 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017344 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017345 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017346
17347 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017348 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017349
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017350 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017351 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017352}
17353
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017354static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17355 struct net_device *dev,
17356 struct cfg80211_ibss_params *params
17357 )
17358{
17359 int ret = 0;
17360
17361 vos_ssr_protect(__func__);
17362 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17363 vos_ssr_unprotect(__func__);
17364
17365 return ret;
17366}
17367
Jeff Johnson295189b2012-06-20 16:38:30 -070017368/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017369 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017370 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017371 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017372static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017373 struct net_device *dev
17374 )
17375{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017376 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017377 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17378 tCsrRoamProfile *pRoamProfile;
17379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017380 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017381 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017382#ifdef WLAN_FEATURE_RMC
17383 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17384#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017385
17386 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017387
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017388 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17389 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17390 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017391 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017392 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017393 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017394 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017395 }
17396
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017397 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17398 hdd_device_modetoString(pAdapter->device_mode),
17399 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017400 if (NULL == pWextState)
17401 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017402 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017403 __func__);
17404 return -EIO;
17405 }
17406
17407 pRoamProfile = &pWextState->roamProfile;
17408
17409 /* Issue disconnect only if interface type is set to IBSS */
17410 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17411 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017412 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017413 __func__);
17414 return -EINVAL;
17415 }
17416
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017417#ifdef WLAN_FEATURE_RMC
17418 /* Clearing add IE of beacon */
17419 if (ccmCfgSetStr(pHddCtx->hHal,
17420 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17421 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17422 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17423 {
17424 hddLog (VOS_TRACE_LEVEL_ERROR,
17425 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17426 return -EINVAL;
17427 }
17428 if (ccmCfgSetInt(pHddCtx->hHal,
17429 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17430 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17431 {
17432 hddLog (VOS_TRACE_LEVEL_ERROR,
17433 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17434 __func__);
17435 return -EINVAL;
17436 }
17437
17438 // Reset WNI_CFG_PROBE_RSP Flags
17439 wlan_hdd_reset_prob_rspies(pAdapter);
17440
17441 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17442 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17443 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17444 {
17445 hddLog (VOS_TRACE_LEVEL_ERROR,
17446 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17447 __func__);
17448 return -EINVAL;
17449 }
17450#endif
17451
Jeff Johnson295189b2012-06-20 16:38:30 -070017452 /* Issue Disconnect request */
17453 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017454 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17455 pAdapter->sessionId,
17456 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17457 if (!HAL_STATUS_SUCCESS(hal_status)) {
17458 hddLog(LOGE,
17459 FL("sme_RoamDisconnect failed hal_status(%d)"),
17460 hal_status);
17461 return -EAGAIN;
17462 }
17463 status = wait_for_completion_timeout(
17464 &pAdapter->disconnect_comp_var,
17465 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17466 if (!status) {
17467 hddLog(LOGE,
17468 FL("wait on disconnect_comp_var failed"));
17469 return -ETIMEDOUT;
17470 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017472 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017473 return 0;
17474}
17475
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017476static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17477 struct net_device *dev
17478 )
17479{
17480 int ret = 0;
17481
17482 vos_ssr_protect(__func__);
17483 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17484 vos_ssr_unprotect(__func__);
17485
17486 return ret;
17487}
17488
Jeff Johnson295189b2012-06-20 16:38:30 -070017489/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017490 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017491 * This function is used to set the phy parameters
17492 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17493 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017494static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017495 u32 changed)
17496{
17497 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17498 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017499 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017500
17501 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017502
17503 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017504 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17505 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017507 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017508 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017510 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017511 }
17512
Jeff Johnson295189b2012-06-20 16:38:30 -070017513 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17514 {
17515 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17516 WNI_CFG_RTS_THRESHOLD_STAMAX :
17517 wiphy->rts_threshold;
17518
17519 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017520 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017522 hddLog(VOS_TRACE_LEVEL_ERROR,
17523 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017524 __func__, rts_threshold);
17525 return -EINVAL;
17526 }
17527
17528 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17529 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017530 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017531 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017532 hddLog(VOS_TRACE_LEVEL_ERROR,
17533 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 __func__, rts_threshold);
17535 return -EIO;
17536 }
17537
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017538 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017539 rts_threshold);
17540 }
17541
17542 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17543 {
17544 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17545 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17546 wiphy->frag_threshold;
17547
17548 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017549 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017550 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017551 hddLog(VOS_TRACE_LEVEL_ERROR,
17552 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017553 frag_threshold);
17554 return -EINVAL;
17555 }
17556
17557 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17558 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017559 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017560 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017561 hddLog(VOS_TRACE_LEVEL_ERROR,
17562 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017563 __func__, frag_threshold);
17564 return -EIO;
17565 }
17566
17567 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17568 frag_threshold);
17569 }
17570
17571 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17572 || (changed & WIPHY_PARAM_RETRY_LONG))
17573 {
17574 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17575 wiphy->retry_short :
17576 wiphy->retry_long;
17577
17578 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17579 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017582 __func__, retry_value);
17583 return -EINVAL;
17584 }
17585
17586 if (changed & WIPHY_PARAM_RETRY_SHORT)
17587 {
17588 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17589 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017590 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017592 hddLog(VOS_TRACE_LEVEL_ERROR,
17593 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017594 __func__, retry_value);
17595 return -EIO;
17596 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017597 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017598 __func__, retry_value);
17599 }
17600 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17601 {
17602 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17603 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017604 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017606 hddLog(VOS_TRACE_LEVEL_ERROR,
17607 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017608 __func__, retry_value);
17609 return -EIO;
17610 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017611 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 __func__, retry_value);
17613 }
17614 }
17615
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017616 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017617 return 0;
17618}
17619
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017620static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17621 u32 changed)
17622{
17623 int ret;
17624
17625 vos_ssr_protect(__func__);
17626 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17627 vos_ssr_unprotect(__func__);
17628
17629 return ret;
17630}
17631
Jeff Johnson295189b2012-06-20 16:38:30 -070017632/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017633 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 * This function is used to set the txpower
17635 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017636static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017637#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17638 struct wireless_dev *wdev,
17639#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017640#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017641 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017642#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017643 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017644#endif
17645 int dbm)
17646{
17647 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017648 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017649 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17650 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017651 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017652
17653 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017654
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017655 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17656 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17657 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017658 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017659 if (0 != status)
17660 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017661 return status;
17662 }
17663
17664 hHal = pHddCtx->hHal;
17665
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017666 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17667 dbm, ccmCfgSetCallback,
17668 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017669 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017670 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017671 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17672 return -EIO;
17673 }
17674
17675 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17676 dbm);
17677
17678 switch(type)
17679 {
17680 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17681 /* Fall through */
17682 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17683 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17686 __func__);
17687 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017688 }
17689 break;
17690 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017692 __func__);
17693 return -EOPNOTSUPP;
17694 break;
17695 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17697 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017698 return -EIO;
17699 }
17700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017701 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017702 return 0;
17703}
17704
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017705static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17706#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17707 struct wireless_dev *wdev,
17708#endif
17709#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17710 enum tx_power_setting type,
17711#else
17712 enum nl80211_tx_power_setting type,
17713#endif
17714 int dbm)
17715{
17716 int ret;
17717 vos_ssr_protect(__func__);
17718 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17719#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17720 wdev,
17721#endif
17722#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17723 type,
17724#else
17725 type,
17726#endif
17727 dbm);
17728 vos_ssr_unprotect(__func__);
17729
17730 return ret;
17731}
17732
Jeff Johnson295189b2012-06-20 16:38:30 -070017733/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017734 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017735 * This function is used to read the txpower
17736 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017737static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017738#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17739 struct wireless_dev *wdev,
17740#endif
17741 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017742{
17743
17744 hdd_adapter_t *pAdapter;
17745 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017746 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017747
Jeff Johnsone7245742012-09-05 17:12:55 -070017748 ENTER();
17749
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017750 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017751 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017752 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017753 *dbm = 0;
17754 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017755 }
17756
Jeff Johnson295189b2012-06-20 16:38:30 -070017757 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17758 if (NULL == pAdapter)
17759 {
17760 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17761 return -ENOENT;
17762 }
17763
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17765 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17766 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017767 wlan_hdd_get_classAstats(pAdapter);
17768 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17769
Jeff Johnsone7245742012-09-05 17:12:55 -070017770 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017771 return 0;
17772}
17773
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017774static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17775#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17776 struct wireless_dev *wdev,
17777#endif
17778 int *dbm)
17779{
17780 int ret;
17781
17782 vos_ssr_protect(__func__);
17783 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17784#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17785 wdev,
17786#endif
17787 dbm);
17788 vos_ssr_unprotect(__func__);
17789
17790 return ret;
17791}
17792
Dustin Brown8c1d4092017-07-28 18:08:01 +053017793/*
17794 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17795 * @stats: summary stats to use as a source
17796 * @info: kernel station_info struct to use as a destination
17797 *
17798 * Return: None
17799 */
17800static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17801 struct station_info *info)
17802{
17803 int i;
17804
17805 info->rx_packets = stats->rx_frm_cnt;
17806 info->tx_packets = 0;
17807 info->tx_retries = 0;
17808 info->tx_failed = 0;
17809
17810 for (i = 0; i < 4; ++i) {
17811 info->tx_packets += stats->tx_frm_cnt[i];
17812 info->tx_retries += stats->multiple_retry_cnt[i];
17813 info->tx_failed += stats->fail_cnt[i];
17814 }
17815
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017816#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17817 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017818 info->filled |= STATION_INFO_TX_PACKETS |
17819 STATION_INFO_TX_RETRIES |
17820 STATION_INFO_TX_FAILED |
17821 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017822#else
17823 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17824 BIT(NL80211_STA_INFO_TX_RETRIES) |
17825 BIT(NL80211_STA_INFO_TX_FAILED) |
17826 BIT(NL80211_STA_INFO_RX_PACKETS);
17827#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017828}
17829
17830/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017831 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17832 * @adapter: sap adapter pointer
17833 * @staid: station id of the client
17834 * @rssi: rssi value to fill
17835 *
17836 * Return: None
17837 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017838void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017839wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17840{
17841 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17842
17843 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17844}
17845
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017846#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17847 !defined(WITH_BACKPORTS)
17848static inline void wlan_hdd_fill_station_info_signal(struct station_info
17849 *sinfo)
17850{
17851 sinfo->filled |= STATION_INFO_SIGNAL;
17852}
17853#else
17854static inline void wlan_hdd_fill_station_info_signal(struct station_info
17855 *sinfo)
17856{
17857 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17858}
17859#endif
17860
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017861/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017862 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17863 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017864 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017865 * @info: kernel station_info struct to populate
17866 *
17867 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17868 * support "station dump" and "station get" for SAP vdevs, even though they
17869 * aren't technically stations.
17870 *
17871 * Return: errno
17872 */
17873static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017874wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17876 const u8* mac,
17877#else
17878 u8* mac,
17879#endif
17880 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017881{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017882 v_MACADDR_t *peerMacAddr;
17883 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017884 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017885 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017886
17887 status = wlan_hdd_get_station_stats(adapter);
17888 if (!VOS_IS_STATUS_SUCCESS(status)) {
17889 hddLog(VOS_TRACE_LEVEL_ERROR,
17890 "Failed to get SAP stats; status:%d", status);
17891 return 0;
17892 }
17893
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017894 peerMacAddr = (v_MACADDR_t *)mac;
17895 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17896 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17897 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17898
17899 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17900 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017901 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017902 }
17903
Dustin Brown8c1d4092017-07-28 18:08:01 +053017904 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17905
17906 return 0;
17907}
17908
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017909static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17911 const u8* mac,
17912#else
17913 u8* mac,
17914#endif
17915 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017916{
17917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17918 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17919 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017920 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017921
17922 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17923 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017924
17925 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17926 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17927 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17928 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17929 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17930 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17931 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017932 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017933 tANI_U16 myRate;
17934 tANI_U16 currentRate = 0;
17935 tANI_U8 maxSpeedMCS = 0;
17936 tANI_U8 maxMCSIdx = 0;
17937 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017938 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017939 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017940 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017941
Leo Chang6f8870f2013-03-26 18:11:36 -070017942#ifdef WLAN_FEATURE_11AC
17943 tANI_U32 vht_mcs_map;
17944 eDataRate11ACMaxMcs vhtMaxMcs;
17945#endif /* WLAN_FEATURE_11AC */
17946
Jeff Johnsone7245742012-09-05 17:12:55 -070017947 ENTER();
17948
Dustin Brown8c1d4092017-07-28 18:08:01 +053017949 status = wlan_hdd_validate_context(pHddCtx);
17950 if (0 != status)
17951 {
17952 return status;
17953 }
17954
17955 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017956 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017957
Jeff Johnson295189b2012-06-20 16:38:30 -070017958 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17959 (0 == ssidlen))
17960 {
17961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17962 " Invalid ssidlen, %d", __func__, ssidlen);
17963 /*To keep GUI happy*/
17964 return 0;
17965 }
17966
Mukul Sharma811205f2014-07-09 21:07:30 +053017967 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17968 {
17969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17970 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017971 /* return a cached value */
17972 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017973 return 0;
17974 }
17975
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017976 wlan_hdd_get_station_stats(pAdapter);
17977 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017978
Kiet Lam3b17fc82013-09-27 05:24:08 +053017979 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017980 wlan_hdd_get_snr(pAdapter, &snr);
17981 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017982 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017983 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017984 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017985 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017986
c_hpothu09f19542014-05-30 21:53:31 +053017987 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017988 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17989 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017990 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017991 {
17992 rate_flags = pAdapter->maxRateFlags;
17993 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017994
Jeff Johnson295189b2012-06-20 16:38:30 -070017995 //convert to the UI units of 100kbps
17996 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17997
17998#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017999 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 -070018000 sinfo->signal,
18001 pCfg->reportMaxLinkSpeed,
18002 myRate,
18003 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018004 (int) pCfg->linkSpeedRssiMid,
18005 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018006 (int) rate_flags,
18007 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018008#endif //LINKSPEED_DEBUG_ENABLED
18009
18010 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18011 {
18012 // we do not want to necessarily report the current speed
18013 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18014 {
18015 // report the max possible speed
18016 rssidx = 0;
18017 }
18018 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18019 {
18020 // report the max possible speed with RSSI scaling
18021 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18022 {
18023 // report the max possible speed
18024 rssidx = 0;
18025 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018026 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018027 {
18028 // report middle speed
18029 rssidx = 1;
18030 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018031 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18032 {
18033 // report middle speed
18034 rssidx = 2;
18035 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018036 else
18037 {
18038 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018039 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018040 }
18041 }
18042 else
18043 {
18044 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18045 hddLog(VOS_TRACE_LEVEL_ERROR,
18046 "%s: Invalid value for reportMaxLinkSpeed: %u",
18047 __func__, pCfg->reportMaxLinkSpeed);
18048 rssidx = 0;
18049 }
18050
18051 maxRate = 0;
18052
18053 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018054 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18055 OperationalRates, &ORLeng))
18056 {
18057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18058 /*To keep GUI happy*/
18059 return 0;
18060 }
18061
Jeff Johnson295189b2012-06-20 16:38:30 -070018062 for (i = 0; i < ORLeng; i++)
18063 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018064 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018065 {
18066 /* Validate Rate Set */
18067 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18068 {
18069 currentRate = supported_data_rate[j].supported_rate[rssidx];
18070 break;
18071 }
18072 }
18073 /* Update MAX rate */
18074 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18075 }
18076
18077 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018078 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18079 ExtendedRates, &ERLeng))
18080 {
18081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18082 /*To keep GUI happy*/
18083 return 0;
18084 }
18085
Jeff Johnson295189b2012-06-20 16:38:30 -070018086 for (i = 0; i < ERLeng; i++)
18087 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018088 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018089 {
18090 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18091 {
18092 currentRate = supported_data_rate[j].supported_rate[rssidx];
18093 break;
18094 }
18095 }
18096 /* Update MAX rate */
18097 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18098 }
c_hpothu79aab322014-07-14 21:11:01 +053018099
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018100 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018101 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018102 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018103 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018104 {
c_hpothu79aab322014-07-14 21:11:01 +053018105 if (rate_flags & eHAL_TX_RATE_VHT80)
18106 mode = 2;
18107 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18108 mode = 1;
18109 else
18110 mode = 0;
18111
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018112 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18113 MCSRates, &MCSLeng))
18114 {
18115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18116 /*To keep GUI happy*/
18117 return 0;
18118 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018119 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018120#ifdef WLAN_FEATURE_11AC
18121 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018122 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018123 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018124 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018125 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018126 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018127 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018128 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018129 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018130 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018131 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018132 maxMCSIdx = 7;
18133 }
18134 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18135 {
18136 maxMCSIdx = 8;
18137 }
18138 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18139 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018140 //VHT20 is supporting 0~8
18141 if (rate_flags & eHAL_TX_RATE_VHT20)
18142 maxMCSIdx = 8;
18143 else
18144 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018145 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018146
c_hpothu79aab322014-07-14 21:11:01 +053018147 if (0 != rssidx)/*check for scaled */
18148 {
18149 //get middle rate MCS index if rssi=1/2
18150 for (i=0; i <= maxMCSIdx; i++)
18151 {
18152 if (sinfo->signal <= rssiMcsTbl[mode][i])
18153 {
18154 maxMCSIdx = i;
18155 break;
18156 }
18157 }
18158 }
18159
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018160 if (rate_flags & eHAL_TX_RATE_VHT80)
18161 {
18162 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18163 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18164 }
18165 else if (rate_flags & eHAL_TX_RATE_VHT40)
18166 {
18167 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18168 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18169 }
18170 else if (rate_flags & eHAL_TX_RATE_VHT20)
18171 {
18172 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18173 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18174 }
18175
Leo Chang6f8870f2013-03-26 18:11:36 -070018176 maxSpeedMCS = 1;
18177 if (currentRate > maxRate)
18178 {
18179 maxRate = currentRate;
18180 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018181
Leo Chang6f8870f2013-03-26 18:11:36 -070018182 }
18183 else
18184#endif /* WLAN_FEATURE_11AC */
18185 {
18186 if (rate_flags & eHAL_TX_RATE_HT40)
18187 {
18188 rateFlag |= 1;
18189 }
18190 if (rate_flags & eHAL_TX_RATE_SGI)
18191 {
18192 rateFlag |= 2;
18193 }
18194
Girish Gowli01abcee2014-07-31 20:18:55 +053018195 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018196 if (rssidx == 1 || rssidx == 2)
18197 {
18198 //get middle rate MCS index if rssi=1/2
18199 for (i=0; i <= 7; i++)
18200 {
18201 if (sinfo->signal <= rssiMcsTbl[mode][i])
18202 {
18203 temp = i+1;
18204 break;
18205 }
18206 }
18207 }
c_hpothu79aab322014-07-14 21:11:01 +053018208
18209 for (i = 0; i < MCSLeng; i++)
18210 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018211 for (j = 0; j < temp; j++)
18212 {
18213 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18214 {
18215 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018216 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018217 break;
18218 }
18219 }
18220 if ((j < temp) && (currentRate > maxRate))
18221 {
18222 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018223 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018224 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018225 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018226 }
18227 }
18228
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018229 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18230 {
18231 maxRate = myRate;
18232 maxSpeedMCS = 1;
18233 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018235 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018236 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018237 {
18238 maxRate = myRate;
18239 if (rate_flags & eHAL_TX_RATE_LEGACY)
18240 {
18241 maxSpeedMCS = 0;
18242 }
18243 else
18244 {
18245 maxSpeedMCS = 1;
18246 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18247 }
18248 }
18249
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018250 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018251 {
18252 sinfo->txrate.legacy = maxRate;
18253#ifdef LINKSPEED_DEBUG_ENABLED
18254 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18255#endif //LINKSPEED_DEBUG_ENABLED
18256 }
18257 else
18258 {
18259 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018260#ifdef WLAN_FEATURE_11AC
18261 sinfo->txrate.nss = 1;
18262 if (rate_flags & eHAL_TX_RATE_VHT80)
18263 {
18264 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18266 defined(WITH_BACKPORTS)
18267 sinfo->txrate.bw = RATE_INFO_BW_80;
18268#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018269 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018270#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018271 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018272 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018273 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018274 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18276 defined(WITH_BACKPORTS)
18277 sinfo->txrate.bw = RATE_INFO_BW_40;
18278#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018279 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018280#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018281 }
18282 else if (rate_flags & eHAL_TX_RATE_VHT20)
18283 {
18284 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18285 }
18286#endif /* WLAN_FEATURE_11AC */
18287 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18288 {
18289 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18290 if (rate_flags & eHAL_TX_RATE_HT40)
18291 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18293 defined(WITH_BACKPORTS)
18294 sinfo->txrate.bw = RATE_INFO_BW_40;
18295#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018296 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018297#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018298 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018300 if (rate_flags & eHAL_TX_RATE_SGI)
18301 {
18302 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18303 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018304
Jeff Johnson295189b2012-06-20 16:38:30 -070018305#ifdef LINKSPEED_DEBUG_ENABLED
18306 pr_info("Reporting MCS rate %d flags %x\n",
18307 sinfo->txrate.mcs,
18308 sinfo->txrate.flags );
18309#endif //LINKSPEED_DEBUG_ENABLED
18310 }
18311 }
18312 else
18313 {
18314 // report current rate instead of max rate
18315
18316 if (rate_flags & eHAL_TX_RATE_LEGACY)
18317 {
18318 //provide to the UI in units of 100kbps
18319 sinfo->txrate.legacy = myRate;
18320#ifdef LINKSPEED_DEBUG_ENABLED
18321 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18322#endif //LINKSPEED_DEBUG_ENABLED
18323 }
18324 else
18325 {
18326 //must be MCS
18327 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018328#ifdef WLAN_FEATURE_11AC
18329 sinfo->txrate.nss = 1;
18330 if (rate_flags & eHAL_TX_RATE_VHT80)
18331 {
18332 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18333 }
18334 else
18335#endif /* WLAN_FEATURE_11AC */
18336 {
18337 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18338 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018339 if (rate_flags & eHAL_TX_RATE_SGI)
18340 {
18341 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18342 }
18343 if (rate_flags & eHAL_TX_RATE_HT40)
18344 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18346 defined(WITH_BACKPORTS)
18347 sinfo->txrate.bw = RATE_INFO_BW_40;
18348#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018349 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018350#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018351 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018352#ifdef WLAN_FEATURE_11AC
18353 else if (rate_flags & eHAL_TX_RATE_VHT80)
18354 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018355#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18356 defined(WITH_BACKPORTS)
18357 sinfo->txrate.bw = RATE_INFO_BW_80;
18358#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018359 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018360#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018361 }
18362#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018363#ifdef LINKSPEED_DEBUG_ENABLED
18364 pr_info("Reporting actual MCS rate %d flags %x\n",
18365 sinfo->txrate.mcs,
18366 sinfo->txrate.flags );
18367#endif //LINKSPEED_DEBUG_ENABLED
18368 }
18369 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018370
18371#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18372 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018373 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018374#else
18375 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18376#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018377
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018378 sinfo->tx_packets =
18379 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18380 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18381 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18382 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18383
18384 sinfo->tx_retries =
18385 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18386 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18387 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18388 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18389
18390 sinfo->tx_failed =
18391 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18392 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18393 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18394 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18395
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018396#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18397 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018398 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018399 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018400 STATION_INFO_TX_PACKETS |
18401 STATION_INFO_TX_RETRIES |
18402 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018403#else
18404 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18405 BIT(NL80211_STA_INFO_TX_PACKETS) |
18406 BIT(NL80211_STA_INFO_TX_RETRIES) |
18407 BIT(NL80211_STA_INFO_TX_FAILED);
18408#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018409
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018410 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018411
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018412 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18413 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018414 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18415 &sinfo->txrate, sizeof(sinfo->txrate));
18416
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018417 if (rate_flags & eHAL_TX_RATE_LEGACY)
18418 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18419 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18420 sinfo->rx_packets);
18421 else
18422 hddLog(LOG1,
18423 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18424 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18425 sinfo->tx_packets, sinfo->rx_packets);
18426
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18428 TRACE_CODE_HDD_CFG80211_GET_STA,
18429 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018430 EXIT();
18431 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018432}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018433#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18434static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18435 const u8* mac, struct station_info *sinfo)
18436#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018437static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18438 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018439#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018440{
18441 int ret;
18442
18443 vos_ssr_protect(__func__);
18444 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18445 vos_ssr_unprotect(__func__);
18446
18447 return ret;
18448}
18449
18450static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018451 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018452{
18453 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018454 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018455 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018456 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018457
Jeff Johnsone7245742012-09-05 17:12:55 -070018458 ENTER();
18459
Jeff Johnson295189b2012-06-20 16:38:30 -070018460 if (NULL == pAdapter)
18461 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018463 return -ENODEV;
18464 }
18465
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018466 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18467 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18468 pAdapter->sessionId, timeout));
18469
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018470 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018471 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018472 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018473 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018474 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018475 }
18476
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018477 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18478 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18479 (pHddCtx->cfg_ini->fhostArpOffload) &&
18480 (eConnectionState_Associated ==
18481 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18482 {
Amar Singhald53568e2013-09-26 11:03:45 -070018483
18484 hddLog(VOS_TRACE_LEVEL_INFO,
18485 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018486 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018487 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18488 {
18489 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018490 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018491 __func__, vos_status);
18492 }
18493 }
18494
Jeff Johnson295189b2012-06-20 16:38:30 -070018495 /**The get power cmd from the supplicant gets updated by the nl only
18496 *on successful execution of the function call
18497 *we are oppositely mapped w.r.t mode in the driver
18498 **/
18499 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18500
18501 if (VOS_STATUS_E_FAILURE == vos_status)
18502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18504 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018505 return -EINVAL;
18506 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018507 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018508 return 0;
18509}
18510
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018511static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18512 struct net_device *dev, bool mode, int timeout)
18513{
18514 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018515
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018516 vos_ssr_protect(__func__);
18517 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18518 vos_ssr_unprotect(__func__);
18519
18520 return ret;
18521}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018522
Jeff Johnson295189b2012-06-20 16:38:30 -070018523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018524static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18525 struct net_device *netdev,
18526 u8 key_index)
18527{
18528 ENTER();
18529 return 0;
18530}
18531
Jeff Johnson295189b2012-06-20 16:38:30 -070018532static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018533 struct net_device *netdev,
18534 u8 key_index)
18535{
18536 int ret;
18537 vos_ssr_protect(__func__);
18538 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18539 vos_ssr_unprotect(__func__);
18540 return ret;
18541}
18542#endif //LINUX_VERSION_CODE
18543
18544#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18545static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18546 struct net_device *dev,
18547 struct ieee80211_txq_params *params)
18548{
18549 ENTER();
18550 return 0;
18551}
18552#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18553static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18554 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018555{
Jeff Johnsone7245742012-09-05 17:12:55 -070018556 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018557 return 0;
18558}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018559#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018560
18561#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18562static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018563 struct net_device *dev,
18564 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018565{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018566 int ret;
18567
18568 vos_ssr_protect(__func__);
18569 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18570 vos_ssr_unprotect(__func__);
18571 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018572}
18573#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18574static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18575 struct ieee80211_txq_params *params)
18576{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018577 int ret;
18578
18579 vos_ssr_protect(__func__);
18580 ret = __wlan_hdd_set_txq_params(wiphy, params);
18581 vos_ssr_unprotect(__func__);
18582 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018583}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018585
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018586static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018587 struct net_device *dev,
18588 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018589{
18590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018591 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018592 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018593 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018594 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018595 v_CONTEXT_t pVosContext = NULL;
18596 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018597
Jeff Johnsone7245742012-09-05 17:12:55 -070018598 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018599
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018600 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018601 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018603 return -EINVAL;
18604 }
18605
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18607 TRACE_CODE_HDD_CFG80211_DEL_STA,
18608 pAdapter->sessionId, pAdapter->device_mode));
18609
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018610 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18611 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018612 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018613 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018614 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018615 }
18616
Jeff Johnson295189b2012-06-20 16:38:30 -070018617 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018618 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018619 )
18620 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018621 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18622 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18623 if(pSapCtx == NULL){
18624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18625 FL("psapCtx is NULL"));
18626 return -ENOENT;
18627 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018628 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18629 {
18630 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18631 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18632 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18633 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018634 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018635 {
18636 v_U16_t i;
18637 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18638 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018639 if ((pSapCtx->aStaInfo[i].isUsed) &&
18640 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018641 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018642 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018643 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018644 ETHER_ADDR_LEN);
18645
Jeff Johnson295189b2012-06-20 16:38:30 -070018646 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018647 "%s: Delete STA with MAC::"
18648 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018649 __func__,
18650 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18651 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018652 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018653 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018654 }
18655 }
18656 }
18657 else
18658 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018659
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018660 vos_status = hdd_softap_GetStaId(pAdapter,
18661 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018662 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18663 {
18664 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018665 "%s: Skip this DEL STA as this is not used::"
18666 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018667 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018668 return -ENOENT;
18669 }
18670
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018671 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018672 {
18673 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018674 "%s: Skip this DEL STA as deauth is in progress::"
18675 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018676 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018677 return -ENOENT;
18678 }
18679
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018680 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018681
Jeff Johnson295189b2012-06-20 16:38:30 -070018682 hddLog(VOS_TRACE_LEVEL_INFO,
18683 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018684 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018685 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018686 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018687
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018688 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018689 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18690 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018691 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018692 hddLog(VOS_TRACE_LEVEL_INFO,
18693 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018694 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018695 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018696 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018697 return -ENOENT;
18698 }
18699
Jeff Johnson295189b2012-06-20 16:38:30 -070018700 }
18701 }
18702
18703 EXIT();
18704
18705 return 0;
18706}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018707
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018708#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018709int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018710 struct net_device *dev,
18711 struct station_del_parameters *param)
18712#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018714int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018715 struct net_device *dev, const u8 *mac)
18716#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018717int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018718 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018719#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018720#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018721{
18722 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018723 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018724
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018725 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018726
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018727#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018728 if (NULL == param) {
18729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018730 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018731 return -EINVAL;
18732 }
18733
18734 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18735 param->subtype, &delStaParams);
18736
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018737#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018738 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018739 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018740#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018741 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18742
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018743 vos_ssr_unprotect(__func__);
18744
18745 return ret;
18746}
18747
18748static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018749 struct net_device *dev,
18750#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18751 const u8 *mac,
18752#else
18753 u8 *mac,
18754#endif
18755 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018756{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018757 hdd_adapter_t *pAdapter;
18758 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018759 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018760#ifdef FEATURE_WLAN_TDLS
18761 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018762
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018763 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018764
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018765 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18766 if (NULL == pAdapter)
18767 {
18768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18769 "%s: Adapter is NULL",__func__);
18770 return -EINVAL;
18771 }
18772 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18773 status = wlan_hdd_validate_context(pHddCtx);
18774 if (0 != status)
18775 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018776 return status;
18777 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018778
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018779 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18780 TRACE_CODE_HDD_CFG80211_ADD_STA,
18781 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018782 mask = params->sta_flags_mask;
18783
18784 set = params->sta_flags_set;
18785
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018787 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18788 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018789
18790 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18791 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018792 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018793 }
18794 }
18795#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018796 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018797 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018798}
18799
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18801static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18802 struct net_device *dev, const u8 *mac,
18803 struct station_parameters *params)
18804#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018805static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18806 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018807#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018808{
18809 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018810
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018811 vos_ssr_protect(__func__);
18812 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18813 vos_ssr_unprotect(__func__);
18814
18815 return ret;
18816}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018817#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018818
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018819static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018820 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018821{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018822 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18823 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018824 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018825 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018826 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018827 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018828
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018829 ENTER();
18830
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018831 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018832 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018835 return -EINVAL;
18836 }
18837
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018838 if (!pmksa) {
18839 hddLog(LOGE, FL("pmksa is NULL"));
18840 return -EINVAL;
18841 }
18842
18843 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018844 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018845 pmksa->bssid, pmksa->pmkid);
18846 return -EINVAL;
18847 }
18848
18849 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18850 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18851
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018852 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18853 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018854 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018855 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018856 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018857 }
18858
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018859 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018860 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18861
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018862 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18863 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018864
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018865 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018866 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018867 &pmk_id, 1, FALSE);
18868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18870 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18871 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018872
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018873 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018874 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018875}
18876
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018877static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18878 struct cfg80211_pmksa *pmksa)
18879{
18880 int ret;
18881
18882 vos_ssr_protect(__func__);
18883 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18884 vos_ssr_unprotect(__func__);
18885
18886 return ret;
18887}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018888
Wilson Yang6507c4e2013-10-01 20:11:19 -070018889
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018890static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018891 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018892{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18894 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018895 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018896 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018897
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018898 ENTER();
18899
Wilson Yang6507c4e2013-10-01 20:11:19 -070018900 /* Validate pAdapter */
18901 if (NULL == pAdapter)
18902 {
18903 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18904 return -EINVAL;
18905 }
18906
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018907 if (!pmksa) {
18908 hddLog(LOGE, FL("pmksa is NULL"));
18909 return -EINVAL;
18910 }
18911
18912 if (!pmksa->bssid) {
18913 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18914 return -EINVAL;
18915 }
18916
Kiet Lam98c46a12014-10-31 15:34:57 -070018917 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18918 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18919
Wilson Yang6507c4e2013-10-01 20:11:19 -070018920 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18921 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018922 if (0 != status)
18923 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018924 return status;
18925 }
18926
18927 /*Retrieve halHandle*/
18928 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18929
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018930 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18931 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18932 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018933 /* Delete the PMKID CSR cache */
18934 if (eHAL_STATUS_SUCCESS !=
18935 sme_RoamDelPMKIDfromCache(halHandle,
18936 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18937 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18938 MAC_ADDR_ARRAY(pmksa->bssid));
18939 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018940 }
18941
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018942 EXIT();
18943 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018944}
18945
Wilson Yang6507c4e2013-10-01 20:11:19 -070018946
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018947static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18948 struct cfg80211_pmksa *pmksa)
18949{
18950 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018951
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018952 vos_ssr_protect(__func__);
18953 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18954 vos_ssr_unprotect(__func__);
18955
18956 return ret;
18957
18958}
18959
18960static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018961{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18963 tHalHandle halHandle;
18964 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018965 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018966
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018967 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018968
18969 /* Validate pAdapter */
18970 if (NULL == pAdapter)
18971 {
18972 hddLog(VOS_TRACE_LEVEL_ERROR,
18973 "%s: Invalid Adapter" ,__func__);
18974 return -EINVAL;
18975 }
18976
18977 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18978 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018979 if (0 != status)
18980 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018981 return status;
18982 }
18983
18984 /*Retrieve halHandle*/
18985 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18986
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018987 /* Flush the PMKID cache in CSR */
18988 if (eHAL_STATUS_SUCCESS !=
18989 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18991 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018992 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018993 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018994 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018995}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018996
18997static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18998{
18999 int ret;
19000
19001 vos_ssr_protect(__func__);
19002 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19003 vos_ssr_unprotect(__func__);
19004
19005 return ret;
19006}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019007#endif
19008
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019009#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019010static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19011 struct net_device *dev,
19012 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019013{
19014 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19015 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019016 hdd_context_t *pHddCtx;
19017 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019018
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019019 ENTER();
19020
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019021 if (NULL == pAdapter)
19022 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019024 return -ENODEV;
19025 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019026 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19027 ret = wlan_hdd_validate_context(pHddCtx);
19028 if (0 != ret)
19029 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019030 return ret;
19031 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019032 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019033 if (NULL == pHddStaCtx)
19034 {
19035 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19036 return -EINVAL;
19037 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019038
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019039 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19040 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19041 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019042 // Added for debug on reception of Re-assoc Req.
19043 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19044 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019045 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019046 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019047 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019048 }
19049
19050#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019051 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019052 ftie->ie_len);
19053#endif
19054
19055 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019056 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19057 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019058 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019059
19060 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019061 return 0;
19062}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019063
19064static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19065 struct net_device *dev,
19066 struct cfg80211_update_ft_ies_params *ftie)
19067{
19068 int ret;
19069
19070 vos_ssr_protect(__func__);
19071 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19072 vos_ssr_unprotect(__func__);
19073
19074 return ret;
19075}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019076#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019077
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019078#ifdef FEATURE_WLAN_SCAN_PNO
19079
19080void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19081 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19082{
19083 int ret;
19084 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19085 hdd_context_t *pHddCtx;
19086
Nirav Shah80830bf2013-12-31 16:35:12 +053019087 ENTER();
19088
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019089 if (NULL == pAdapter)
19090 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019092 "%s: HDD adapter is Null", __func__);
19093 return ;
19094 }
19095
19096 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19097 if (NULL == pHddCtx)
19098 {
19099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19100 "%s: HDD context is Null!!!", __func__);
19101 return ;
19102 }
19103
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019104 spin_lock(&pHddCtx->schedScan_lock);
19105 if (TRUE == pHddCtx->isWiphySuspended)
19106 {
19107 pHddCtx->isSchedScanUpdatePending = TRUE;
19108 spin_unlock(&pHddCtx->schedScan_lock);
19109 hddLog(VOS_TRACE_LEVEL_INFO,
19110 "%s: Update cfg80211 scan database after it resume", __func__);
19111 return ;
19112 }
19113 spin_unlock(&pHddCtx->schedScan_lock);
19114
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019115 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19116
19117 if (0 > ret)
19118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019119 else
19120 {
19121 /* Acquire wakelock to handle the case where APP's tries to suspend
19122 * immediatly after the driver gets connect request(i.e after pno)
19123 * from supplicant, this result in app's is suspending and not able
19124 * to process the connect request to AP */
19125 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19126 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019127 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19129 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019130}
19131
19132/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019133 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019134 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019135 */
19136static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19137{
19138 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19139 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019140 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19142 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019143
19144 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19145 {
19146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19147 "%s: PNO is allowed only in STA interface", __func__);
19148 return eHAL_STATUS_FAILURE;
19149 }
19150
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019151 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19152
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019153 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019154 * active sessions. PNO is allowed only in case when sap session
19155 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019156 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019157 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19158 {
19159 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019160 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019161
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019162 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19163 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19164 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19165 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019166 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19167 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019168 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019169 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019170 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019171 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019172 }
19173 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19174 pAdapterNode = pNext;
19175 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019176 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019177}
19178
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019179void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19180{
19181 hdd_adapter_t *pAdapter = callbackContext;
19182 hdd_context_t *pHddCtx;
19183
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019184 ENTER();
19185
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019186 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19187 {
19188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19189 FL("Invalid adapter or adapter has invalid magic"));
19190 return;
19191 }
19192
19193 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19194 if (0 != wlan_hdd_validate_context(pHddCtx))
19195 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019196 return;
19197 }
19198
c_hpothub53c45d2014-08-18 16:53:14 +053019199 if (VOS_STATUS_SUCCESS != status)
19200 {
19201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019202 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019203 pHddCtx->isPnoEnable = FALSE;
19204 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019205
19206 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19207 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019208 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019209}
19210
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19212 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19213/**
19214 * hdd_config_sched_scan_plan() - configures the sched scan plans
19215 * from the framework.
19216 * @pno_req: pointer to PNO scan request
19217 * @request: pointer to scan request from framework
19218 *
19219 * Return: None
19220 */
19221static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19222 struct cfg80211_sched_scan_request *request,
19223 hdd_context_t *hdd_ctx)
19224{
19225 v_U32_t i = 0;
19226
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019227 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019228 for (i = 0; i < request->n_scan_plans; i++)
19229 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019230 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19231 request->scan_plans[i].iterations;
19232 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19233 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019234 }
19235}
19236#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019237static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019238 struct cfg80211_sched_scan_request *request,
19239 hdd_context_t *hdd_ctx)
19240{
19241 v_U32_t i, temp_int;
19242 /* Driver gets only one time interval which is hardcoded in
19243 * supplicant for 10000ms. Taking power consumption into account 6
19244 * timers will be used, Timervalue is increased exponentially
19245 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19246 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19247 * If it is set to 0 only one timer will be used and PNO scan cycle
19248 * will be repeated after each interval specified by supplicant
19249 * till PNO is disabled.
19250 */
19251 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019252 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019253 HDD_PNO_SCAN_TIMERS_SET_ONE;
19254 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019255 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019256 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19257
19258 temp_int = (request->interval)/1000;
19259 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19260 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19261 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019262 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019263 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019264 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019265 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019266 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019267 temp_int *= 2;
19268 }
19269 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019270 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019271}
19272#endif
19273
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019274/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019275 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19276 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019277 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019278static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019279 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19280{
19281 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019282 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019283 hdd_context_t *pHddCtx;
19284 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019285 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019286 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19287 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019288 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19289 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019290 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019291 hdd_config_t *pConfig = NULL;
19292 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019294 ENTER();
19295
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019296 if (NULL == pAdapter)
19297 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019299 "%s: HDD adapter is Null", __func__);
19300 return -ENODEV;
19301 }
19302
19303 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019304 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019305
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019306 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019307 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019308 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019309 }
19310
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019311 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019312 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19313 if (NULL == hHal)
19314 {
19315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19316 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019317 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019318 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019319 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19320 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19321 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019322 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019323 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019324 {
19325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19326 "%s: aborting the existing scan is unsuccessfull", __func__);
19327 return -EBUSY;
19328 }
19329
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019330 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019331 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019333 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019334 return -EBUSY;
19335 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019336
c_hpothu37f21312014-04-09 21:49:54 +053019337 if (TRUE == pHddCtx->isPnoEnable)
19338 {
19339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19340 FL("already PNO is enabled"));
19341 return -EBUSY;
19342 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019343
19344 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19345 {
19346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19347 "%s: abort ROC failed ", __func__);
19348 return -EBUSY;
19349 }
19350
c_hpothu37f21312014-04-09 21:49:54 +053019351 pHddCtx->isPnoEnable = TRUE;
19352
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019353 pnoRequest.enable = 1; /*Enable PNO */
19354 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019355
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019356 if (( !pnoRequest.ucNetworksCount ) ||
19357 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019358 {
19359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019360 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019361 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019362 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019363 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019364 goto error;
19365 }
19366
19367 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19368 {
19369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019370 "%s: Incorrect number of channels %d",
19371 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019372 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019373 goto error;
19374 }
19375
19376 /* Framework provides one set of channels(all)
19377 * common for all saved profile */
19378 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19379 channels_allowed, &num_channels_allowed))
19380 {
19381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19382 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019383 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019384 goto error;
19385 }
19386 /* Checking each channel against allowed channel list */
19387 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019388 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019389 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019390 char chList [(request->n_channels*5)+1];
19391 int len;
19392 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019393 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019394 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019395 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019396 if (request->channels[i]->hw_value == channels_allowed[indx])
19397 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019398 if ((!pConfig->enableDFSPnoChnlScan) &&
19399 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19400 {
19401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19402 "%s : Dropping DFS channel : %d",
19403 __func__,channels_allowed[indx]);
19404 num_ignore_dfs_ch++;
19405 break;
19406 }
19407
Nirav Shah80830bf2013-12-31 16:35:12 +053019408 valid_ch[num_ch++] = request->channels[i]->hw_value;
19409 len += snprintf(chList+len, 5, "%d ",
19410 request->channels[i]->hw_value);
19411 break ;
19412 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019413 }
19414 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019415 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019416
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019417 /*If all channels are DFS and dropped, then ignore the PNO request*/
19418 if (num_ignore_dfs_ch == request->n_channels)
19419 {
19420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19421 "%s : All requested channels are DFS channels", __func__);
19422 ret = -EINVAL;
19423 goto error;
19424 }
19425 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019426
19427 pnoRequest.aNetworks =
19428 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19429 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019430 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019431 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19432 FL("failed to allocate memory aNetworks %u"),
19433 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19434 goto error;
19435 }
19436 vos_mem_zero(pnoRequest.aNetworks,
19437 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19438
19439 /* Filling per profile params */
19440 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19441 {
19442 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019443 request->match_sets[i].ssid.ssid_len;
19444
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019445 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19446 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019447 {
19448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019449 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019450 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019451 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019452 goto error;
19453 }
19454
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019455 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019456 request->match_sets[i].ssid.ssid,
19457 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19459 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019460 i, pnoRequest.aNetworks[i].ssId.ssId);
19461 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19462 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19463 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019464
19465 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019466 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19467 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019468
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019469 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019470 }
19471
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019472 for (i = 0; i < request->n_ssids; i++)
19473 {
19474 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019475 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019476 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019477 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019478 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019479 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019480 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019481 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019482 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019483 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019484 break;
19485 }
19486 j++;
19487 }
19488 }
19489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19490 "Number of hidden networks being Configured = %d",
19491 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019493 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019494
19495 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19496 if (pnoRequest.p24GProbeTemplate == NULL)
19497 {
19498 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19499 FL("failed to allocate memory p24GProbeTemplate %u"),
19500 SIR_PNO_MAX_PB_REQ_SIZE);
19501 goto error;
19502 }
19503
19504 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19505 if (pnoRequest.p5GProbeTemplate == NULL)
19506 {
19507 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19508 FL("failed to allocate memory p5GProbeTemplate %u"),
19509 SIR_PNO_MAX_PB_REQ_SIZE);
19510 goto error;
19511 }
19512
19513 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19514 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19515
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019516 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19517 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019518 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019519 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19520 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19521 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019522
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019523 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19524 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19525 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019526 }
19527
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019528 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019529
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019530 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019531
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019532 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019533 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19534 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019535 pAdapter->pno_req_status = 0;
19536
Nirav Shah80830bf2013-12-31 16:35:12 +053019537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19538 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019539 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19540 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019541
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019542 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019543 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019544 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19545 if (eHAL_STATUS_SUCCESS != status)
19546 {
19547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019548 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019549 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019550 goto error;
19551 }
19552
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019553 ret = wait_for_completion_timeout(
19554 &pAdapter->pno_comp_var,
19555 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19556 if (0 >= ret)
19557 {
19558 // Did not receive the response for PNO enable in time.
19559 // Assuming the PNO enable was success.
19560 // Returning error from here, because we timeout, results
19561 // in side effect of Wifi (Wifi Setting) not to work.
19562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19563 FL("Timed out waiting for PNO to be Enabled"));
19564 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019565 }
19566
19567 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019568 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019569
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019570error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19572 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019573 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019574 if (pnoRequest.aNetworks)
19575 vos_mem_free(pnoRequest.aNetworks);
19576 if (pnoRequest.p24GProbeTemplate)
19577 vos_mem_free(pnoRequest.p24GProbeTemplate);
19578 if (pnoRequest.p5GProbeTemplate)
19579 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019580
19581 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019582 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019583}
19584
19585/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019586 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19587 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019588 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019589static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19590 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19591{
19592 int ret;
19593
19594 vos_ssr_protect(__func__);
19595 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19596 vos_ssr_unprotect(__func__);
19597
19598 return ret;
19599}
19600
19601/*
19602 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19603 * Function to disable PNO
19604 */
19605static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019606 struct net_device *dev)
19607{
19608 eHalStatus status = eHAL_STATUS_FAILURE;
19609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19610 hdd_context_t *pHddCtx;
19611 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019612 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019613 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019614
19615 ENTER();
19616
19617 if (NULL == pAdapter)
19618 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019620 "%s: HDD adapter is Null", __func__);
19621 return -ENODEV;
19622 }
19623
19624 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019625
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019626 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019627 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019629 "%s: HDD context is Null", __func__);
19630 return -ENODEV;
19631 }
19632
19633 /* The return 0 is intentional when isLogpInProgress and
19634 * isLoadUnloadInProgress. We did observe a crash due to a return of
19635 * failure in sched_scan_stop , especially for a case where the unload
19636 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19637 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19638 * success. If it returns a failure , then its next invocation due to the
19639 * clean up of the second interface will have the dev pointer corresponding
19640 * to the first one leading to a crash.
19641 */
19642 if (pHddCtx->isLogpInProgress)
19643 {
19644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19645 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019646 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019647 return ret;
19648 }
19649
Mihir Shete18156292014-03-11 15:38:30 +053019650 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019651 {
19652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19653 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19654 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019655 }
19656
19657 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19658 if (NULL == hHal)
19659 {
19660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19661 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019662 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019663 }
19664
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019665 pnoRequest.enable = 0; /* Disable PNO */
19666 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019667
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019668 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19669 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19670 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019671
19672 INIT_COMPLETION(pAdapter->pno_comp_var);
19673 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19674 pnoRequest.callbackContext = pAdapter;
19675 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019676 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019677 pAdapter->sessionId,
19678 NULL, pAdapter);
19679 if (eHAL_STATUS_SUCCESS != status)
19680 {
19681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19682 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019683 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019684 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019685 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019686 ret = wait_for_completion_timeout(
19687 &pAdapter->pno_comp_var,
19688 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19689 if (0 >= ret)
19690 {
19691 // Did not receive the response for PNO disable in time.
19692 // Assuming the PNO disable was success.
19693 // Returning error from here, because we timeout, results
19694 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019696 FL("Timed out waiting for PNO to be disabled"));
19697 ret = 0;
19698 }
19699
19700 ret = pAdapter->pno_req_status;
19701 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019702
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019703error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019705 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019706
19707 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019708 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019709}
19710
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019711/*
19712 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19713 * NL interface to disable PNO
19714 */
19715static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19716 struct net_device *dev)
19717{
19718 int ret;
19719
19720 vos_ssr_protect(__func__);
19721 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19722 vos_ssr_unprotect(__func__);
19723
19724 return ret;
19725}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019726#endif /*FEATURE_WLAN_SCAN_PNO*/
19727
19728
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019729#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019730#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019731static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19732 struct net_device *dev,
19733 u8 *peer, u8 action_code,
19734 u8 dialog_token,
19735 u16 status_code, u32 peer_capability,
19736 const u8 *buf, size_t len)
19737#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19739 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019740static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19741 struct net_device *dev,
19742 const u8 *peer, u8 action_code,
19743 u8 dialog_token, u16 status_code,
19744 u32 peer_capability, bool initiator,
19745 const u8 *buf, size_t len)
19746#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19747static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19748 struct net_device *dev,
19749 const u8 *peer, u8 action_code,
19750 u8 dialog_token, u16 status_code,
19751 u32 peer_capability, const u8 *buf,
19752 size_t len)
19753#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19754static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19755 struct net_device *dev,
19756 u8 *peer, u8 action_code,
19757 u8 dialog_token,
19758 u16 status_code, u32 peer_capability,
19759 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019760#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019761static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19762 struct net_device *dev,
19763 u8 *peer, u8 action_code,
19764 u8 dialog_token,
19765 u16 status_code, const u8 *buf,
19766 size_t len)
19767#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019768#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019769{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019770 hdd_adapter_t *pAdapter;
19771 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019772 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019773 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019774 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019775 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019776 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019777 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019778#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019779 u32 peer_capability = 0;
19780#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019781 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019782 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019783 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019784
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019785 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19786 if (NULL == pAdapter)
19787 {
19788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19789 "%s: Adapter is NULL",__func__);
19790 return -EINVAL;
19791 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019792 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19793 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19794 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019795
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019796 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019797 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019800 "Invalid arguments");
19801 return -EINVAL;
19802 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019803
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019804 if (pHddCtx->isLogpInProgress)
19805 {
19806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19807 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019808 wlan_hdd_tdls_set_link_status(pAdapter,
19809 peer,
19810 eTDLS_LINK_IDLE,
19811 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019812 return -EBUSY;
19813 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019814
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019815 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19816 {
19817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19818 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19819 return -EAGAIN;
19820 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019821
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019822 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19823 if (!pHddTdlsCtx) {
19824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19825 "%s: pHddTdlsCtx not valid.", __func__);
19826 }
19827
Hoonki Lee27511902013-03-14 18:19:06 -070019828 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019829 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019831 "%s: TDLS mode is disabled OR not enabled in FW."
19832 MAC_ADDRESS_STR " action %d declined.",
19833 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019834 return -ENOTSUPP;
19835 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019836
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019837 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19838
19839 if( NULL == pHddStaCtx )
19840 {
19841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19842 "%s: HDD station context NULL ",__func__);
19843 return -EINVAL;
19844 }
19845
19846 /* STA should be connected and authenticated
19847 * before sending any TDLS frames
19848 */
19849 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19850 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19851 {
19852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19853 "STA is not connected or unauthenticated. "
19854 "connState %u, uIsAuthenticated %u",
19855 pHddStaCtx->conn_info.connState,
19856 pHddStaCtx->conn_info.uIsAuthenticated);
19857 return -EAGAIN;
19858 }
19859
Hoonki Lee27511902013-03-14 18:19:06 -070019860 /* other than teardown frame, other mgmt frames are not sent if disabled */
19861 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19862 {
19863 /* if tdls_mode is disabled to respond to peer's request */
19864 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19865 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019867 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019868 " TDLS mode is disabled. action %d declined.",
19869 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019870
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019871 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019872 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019873
19874 if (vos_max_concurrent_connections_reached())
19875 {
19876 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19877 return -EINVAL;
19878 }
Hoonki Lee27511902013-03-14 18:19:06 -070019879 }
19880
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019881 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19882 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019883 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019884 {
19885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019886 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019887 " TDLS setup is ongoing. action %d declined.",
19888 __func__, MAC_ADDR_ARRAY(peer), action_code);
19889 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019890 }
19891 }
19892
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019893 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19894 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019895 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019896 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19897 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019898 {
19899 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19900 we return error code at 'add_station()'. Hence we have this
19901 check again in addtion to add_station().
19902 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019903 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019904 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19906 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019907 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19908 __func__, MAC_ADDR_ARRAY(peer), action_code,
19909 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019910 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019911 }
19912 else
19913 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019914 /* maximum reached. tweak to send error code to peer and return
19915 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019916 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19918 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019919 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19920 __func__, MAC_ADDR_ARRAY(peer), status_code,
19921 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019922 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019923 /* fall through to send setup resp with failure status
19924 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019925 }
19926 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019927 else
19928 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019929 mutex_lock(&pHddCtx->tdls_lock);
19930 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019931 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019932 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019933 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019935 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19936 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019937 return -EPERM;
19938 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019939 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019940 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019941 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019942
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019944 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019945 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19946 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019947
Hoonki Leea34dd892013-02-05 22:56:02 -080019948 /*Except teardown responder will not be used so just make 0*/
19949 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019950 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019951 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019952
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019953 mutex_lock(&pHddCtx->tdls_lock);
19954 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019955
19956 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19957 responder = pTdlsPeer->is_responder;
19958 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019959 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019961 "%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 -070019962 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19963 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019964 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019965 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019966 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019967 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019968 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019969
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019970 /* Discard TDLS setup if peer is removed by user app */
19971 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19972 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19973 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19974 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19975
19976 mutex_lock(&pHddCtx->tdls_lock);
19977 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19978 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19979 mutex_unlock(&pHddCtx->tdls_lock);
19980 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19981 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19982 MAC_ADDR_ARRAY(peer), action_code);
19983 return -EINVAL;
19984 }
19985 mutex_unlock(&pHddCtx->tdls_lock);
19986 }
19987
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019988 /* For explicit trigger of DIS_REQ come out of BMPS for
19989 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019990 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019991 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019992 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19993 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019994 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019995 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019997 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19998 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019999 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20000 if (status != VOS_STATUS_SUCCESS) {
20001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020002 } else {
20003 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020004 }
Hoonki Lee14621352013-04-16 17:51:19 -070020005 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020006 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020007 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020008 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20009 }
20010 }
Hoonki Lee14621352013-04-16 17:51:19 -070020011 }
20012
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020013 /* make sure doesn't call send_mgmt() while it is pending */
20014 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20015 {
20016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020017 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020018 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020019 ret = -EBUSY;
20020 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020021 }
20022
20023 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020024 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20025
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020026 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20027 pAdapter->sessionId, peer, action_code, dialog_token,
20028 status_code, peer_capability, (tANI_U8 *)buf, len,
20029 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020030
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020031 if (VOS_STATUS_SUCCESS != status)
20032 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20034 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020035 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020036 ret = -EINVAL;
20037 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020038 }
20039
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20041 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20042 WAIT_TIME_TDLS_MGMT);
20043
Hoonki Leed37cbb32013-04-20 00:31:14 -070020044 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20045 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20046
20047 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020048 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020050 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020051 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020052 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020053
20054 if (pHddCtx->isLogpInProgress)
20055 {
20056 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20057 "%s: LOGP in Progress. Ignore!!!", __func__);
20058 return -EAGAIN;
20059 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020060 if (rc <= 0)
20061 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20062 WLAN_LOG_INDICATOR_HOST_DRIVER,
20063 WLAN_LOG_REASON_HDD_TIME_OUT,
20064 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020065
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020066 ret = -EINVAL;
20067 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020068 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020069 else
20070 {
20071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20072 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20073 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20074 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020075
Gopichand Nakkala05922802013-03-14 12:23:19 -070020076 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020077 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020078 ret = max_sta_failed;
20079 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020080 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020081
Hoonki Leea34dd892013-02-05 22:56:02 -080020082 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20083 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020084 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20086 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020087 }
20088 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20089 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020090 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20092 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020093 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020094
20095 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020096
20097tx_failed:
20098 /* add_station will be called before sending TDLS_SETUP_REQ and
20099 * TDLS_SETUP_RSP and as part of add_station driver will enable
20100 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20101 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20102 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20103 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20104 */
20105
20106 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20107 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20108 wlan_hdd_tdls_check_bmps(pAdapter);
20109 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020110}
20111
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020112#if TDLS_MGMT_VERSION2
20113static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20114 u8 *peer, u8 action_code, u8 dialog_token,
20115 u16 status_code, u32 peer_capability,
20116 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020117#else /* TDLS_MGMT_VERSION2 */
20118#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20119static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20120 struct net_device *dev,
20121 const u8 *peer, u8 action_code,
20122 u8 dialog_token, u16 status_code,
20123 u32 peer_capability, bool initiator,
20124 const u8 *buf, size_t len)
20125#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20126static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20127 struct net_device *dev,
20128 const u8 *peer, u8 action_code,
20129 u8 dialog_token, u16 status_code,
20130 u32 peer_capability, const u8 *buf,
20131 size_t len)
20132#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20133static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20134 struct net_device *dev,
20135 u8 *peer, u8 action_code,
20136 u8 dialog_token,
20137 u16 status_code, u32 peer_capability,
20138 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020139#else
20140static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20141 u8 *peer, u8 action_code, u8 dialog_token,
20142 u16 status_code, const u8 *buf, size_t len)
20143#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020144#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020145{
20146 int ret;
20147
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020148 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020149#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020150 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20151 dialog_token, status_code,
20152 peer_capability, buf, len);
20153#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20155 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020156 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20157 dialog_token, status_code,
20158 peer_capability, initiator,
20159 buf, len);
20160#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20161 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20162 dialog_token, status_code,
20163 peer_capability, buf, len);
20164#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20165 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20166 dialog_token, status_code,
20167 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020168#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020169 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20170 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020171#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020172#endif
20173 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020174
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020175 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020176}
Atul Mittal115287b2014-07-08 13:26:33 +053020177
20178int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020179#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20180 const u8 *peer,
20181#else
Atul Mittal115287b2014-07-08 13:26:33 +053020182 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020183#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020184 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020185 cfg80211_exttdls_callback callback)
20186{
20187
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020188 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020189 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020190 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20192 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20193 __func__, MAC_ADDR_ARRAY(peer));
20194
20195 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20196 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20197
20198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020199 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20200 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20201 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020202 return -ENOTSUPP;
20203 }
20204
20205 /* To cater the requirement of establishing the TDLS link
20206 * irrespective of the data traffic , get an entry of TDLS peer.
20207 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020208 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020209 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20210 if (pTdlsPeer == NULL) {
20211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20212 "%s: peer " MAC_ADDRESS_STR " not existing",
20213 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020214 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020215 return -EINVAL;
20216 }
20217
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020218 /* check FW TDLS Off Channel capability */
20219 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020220 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020221 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020222 {
20223 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20224 pTdlsPeer->peerParams.global_operating_class =
20225 tdls_peer_params->global_operating_class;
20226 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20227 pTdlsPeer->peerParams.min_bandwidth_kbps =
20228 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020229 /* check configured channel is valid, non dfs and
20230 * not current operating channel */
20231 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20232 tdls_peer_params->channel)) &&
20233 (pHddStaCtx) &&
20234 (tdls_peer_params->channel !=
20235 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020236 {
20237 pTdlsPeer->isOffChannelConfigured = TRUE;
20238 }
20239 else
20240 {
20241 pTdlsPeer->isOffChannelConfigured = FALSE;
20242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20243 "%s: Configured Tdls Off Channel is not valid", __func__);
20244
20245 }
20246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020247 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20248 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020249 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020250 pTdlsPeer->isOffChannelConfigured,
20251 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020252 }
20253 else
20254 {
20255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020256 "%s: TDLS off channel FW capability %d, "
20257 "host capab %d or Invalid TDLS Peer Params", __func__,
20258 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20259 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020260 }
20261
Atul Mittal115287b2014-07-08 13:26:33 +053020262 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20263
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020264 mutex_unlock(&pHddCtx->tdls_lock);
20265
Atul Mittal115287b2014-07-08 13:26:33 +053020266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20267 " %s TDLS Add Force Peer Failed",
20268 __func__);
20269 return -EINVAL;
20270 }
20271 /*EXT TDLS*/
20272
20273 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020274 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20276 " %s TDLS set callback Failed",
20277 __func__);
20278 return -EINVAL;
20279 }
20280
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020281 mutex_unlock(&pHddCtx->tdls_lock);
20282
Atul Mittal115287b2014-07-08 13:26:33 +053020283 return(0);
20284
20285}
20286
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020287int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20288#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20289 const u8 *peer
20290#else
20291 u8 *peer
20292#endif
20293)
Atul Mittal115287b2014-07-08 13:26:33 +053020294{
20295
20296 hddTdlsPeer_t *pTdlsPeer;
20297 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020298
Atul Mittal115287b2014-07-08 13:26:33 +053020299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20300 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20301 __func__, MAC_ADDR_ARRAY(peer));
20302
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020303 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20305 return -EINVAL;
20306 }
20307
Atul Mittal115287b2014-07-08 13:26:33 +053020308 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20309 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20310
20311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020312 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20313 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20314 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020315 return -ENOTSUPP;
20316 }
20317
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020318 mutex_lock(&pHddCtx->tdls_lock);
20319 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020320
20321 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020322 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020324 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020325 __func__, MAC_ADDR_ARRAY(peer));
20326 return -EINVAL;
20327 }
20328 else {
20329 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20330 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020331 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20332 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020333 /* if channel switch is configured, reset
20334 the channel for this peer */
20335 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20336 {
20337 pTdlsPeer->peerParams.channel = 0;
20338 pTdlsPeer->isOffChannelConfigured = FALSE;
20339 }
Atul Mittal115287b2014-07-08 13:26:33 +053020340 }
20341
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020342 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020343 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020345 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020346 }
Atul Mittal115287b2014-07-08 13:26:33 +053020347
20348 /*EXT TDLS*/
20349
20350 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020351 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20353 " %s TDLS set callback Failed",
20354 __func__);
20355 return -EINVAL;
20356 }
Atul Mittal115287b2014-07-08 13:26:33 +053020357
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020358 mutex_unlock(&pHddCtx->tdls_lock);
20359
20360 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020361}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020362static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20364 const u8 *peer,
20365#else
20366 u8 *peer,
20367#endif
20368 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020369{
20370 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020372 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020373 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020374
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020375 ENTER();
20376
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020377 if (!pAdapter) {
20378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20379 return -EINVAL;
20380 }
20381
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020382 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20383 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20384 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020385 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020386 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020388 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020389 return -EINVAL;
20390 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020391
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020392 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020393 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020394 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020395 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020396 }
20397
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020398
20399 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020400 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020401 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020403 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20404 "Cannot process TDLS commands",
20405 pHddCtx->cfg_ini->fEnableTDLSSupport,
20406 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020407 return -ENOTSUPP;
20408 }
20409
20410 switch (oper) {
20411 case NL80211_TDLS_ENABLE_LINK:
20412 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020413 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020414 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020415 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20416 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020417 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020418 tANI_U16 numCurrTdlsPeers = 0;
20419 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020420 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020421 tSirMacAddr peerMac;
20422 int channel;
20423 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020424
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20426 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20427 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020428
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020429 mutex_lock(&pHddCtx->tdls_lock);
20430 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020431 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020432 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020433 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20435 " (oper %d) not exsting. ignored",
20436 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20437 return -EINVAL;
20438 }
20439
20440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20441 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20442 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20443 "NL80211_TDLS_ENABLE_LINK");
20444
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020445 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20446 {
20447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20448 MAC_ADDRESS_STR " failed",
20449 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020450 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020451 return -EINVAL;
20452 }
20453
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020454 /* before starting tdls connection, set tdls
20455 * off channel established status to default value */
20456 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020457
20458 mutex_unlock(&pHddCtx->tdls_lock);
20459
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020460 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020461 /* TDLS Off Channel, Disable tdls channel switch,
20462 when there are more than one tdls link */
20463 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020464 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020465 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020466 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020467 /* get connected peer and send disable tdls off chan */
20468 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020469 if ((connPeer) &&
20470 (connPeer->isOffChannelSupported == TRUE) &&
20471 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020472 {
20473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20474 "%s: More then one peer connected, Disable "
20475 "TDLS channel switch", __func__);
20476
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020477 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020478 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20479 channel = connPeer->peerParams.channel;
20480
20481 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020482
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020483 ret = sme_SendTdlsChanSwitchReq(
20484 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020485 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020486 peerMac,
20487 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020488 TDLS_OFF_CHANNEL_BW_OFFSET,
20489 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020490 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020491 hddLog(VOS_TRACE_LEVEL_ERROR,
20492 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020493 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020494 }
20495 else
20496 {
20497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20498 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020499 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020500 "isOffChannelConfigured %d",
20501 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020502 (connPeer ? (connPeer->isOffChannelSupported)
20503 : -1),
20504 (connPeer ? (connPeer->isOffChannelConfigured)
20505 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020506 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020507 }
20508 }
20509
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020510 mutex_lock(&pHddCtx->tdls_lock);
20511 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20512 if ( NULL == pTdlsPeer ) {
20513 mutex_unlock(&pHddCtx->tdls_lock);
20514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20515 "%s: " MAC_ADDRESS_STR
20516 " (oper %d) peer got freed in other context. ignored",
20517 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20518 return -EINVAL;
20519 }
20520 peer_status = pTdlsPeer->link_status;
20521 mutex_unlock(&pHddCtx->tdls_lock);
20522
20523 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020524 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020525 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020526
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020527 if (0 != wlan_hdd_tdls_get_link_establish_params(
20528 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020530 return -EINVAL;
20531 }
20532 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020533
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020534 ret = sme_SendTdlsLinkEstablishParams(
20535 WLAN_HDD_GET_HAL_CTX(pAdapter),
20536 pAdapter->sessionId, peer,
20537 &tdlsLinkEstablishParams);
20538 if (ret != VOS_STATUS_SUCCESS) {
20539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20540 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020541 /* Send TDLS peer UAPSD capabilities to the firmware and
20542 * register with the TL on after the response for this operation
20543 * is received .
20544 */
20545 ret = wait_for_completion_interruptible_timeout(
20546 &pAdapter->tdls_link_establish_req_comp,
20547 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020548
20549 mutex_lock(&pHddCtx->tdls_lock);
20550 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20551 if ( NULL == pTdlsPeer ) {
20552 mutex_unlock(&pHddCtx->tdls_lock);
20553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20554 "%s %d: " MAC_ADDRESS_STR
20555 " (oper %d) peer got freed in other context. ignored",
20556 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20557 (int)oper);
20558 return -EINVAL;
20559 }
20560 peer_status = pTdlsPeer->link_status;
20561 mutex_unlock(&pHddCtx->tdls_lock);
20562
20563 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020564 {
20565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020566 FL("Link Establish Request Failed Status %ld"),
20567 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020568 return -EINVAL;
20569 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020570 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020571
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020572 mutex_lock(&pHddCtx->tdls_lock);
20573 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20574 if ( NULL == pTdlsPeer ) {
20575 mutex_unlock(&pHddCtx->tdls_lock);
20576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20577 "%s: " MAC_ADDRESS_STR
20578 " (oper %d) peer got freed in other context. ignored",
20579 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20580 return -EINVAL;
20581 }
20582
Atul Mittal115287b2014-07-08 13:26:33 +053020583 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20584 eTDLS_LINK_CONNECTED,
20585 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020586 staDesc.ucSTAId = pTdlsPeer->staId;
20587 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020588
20589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20590 "%s: tdlsLinkEstablishParams of peer "
20591 MAC_ADDRESS_STR "uapsdQueues: %d"
20592 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20593 "isResponder: %d peerstaId: %d",
20594 __func__,
20595 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20596 tdlsLinkEstablishParams.uapsdQueues,
20597 tdlsLinkEstablishParams.qos,
20598 tdlsLinkEstablishParams.maxSp,
20599 tdlsLinkEstablishParams.isBufSta,
20600 tdlsLinkEstablishParams.isOffChannelSupported,
20601 tdlsLinkEstablishParams.isResponder,
20602 pTdlsPeer->staId);
20603
20604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20605 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20606 __func__,
20607 staDesc.ucSTAId,
20608 staDesc.ucQosEnabled);
20609
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020610 ret = WLANTL_UpdateTdlsSTAClient(
20611 pHddCtx->pvosContext,
20612 &staDesc);
20613 if (ret != VOS_STATUS_SUCCESS) {
20614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20615 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020616
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020617 /* Mark TDLS client Authenticated .*/
20618 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20619 pTdlsPeer->staId,
20620 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020621 if (VOS_STATUS_SUCCESS == status)
20622 {
Hoonki Lee14621352013-04-16 17:51:19 -070020623 if (pTdlsPeer->is_responder == 0)
20624 {
20625 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020626 tdlsConnInfo_t *tdlsInfo;
20627
20628 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20629
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020630 if (!vos_timer_is_initialized(
20631 &pTdlsPeer->initiatorWaitTimeoutTimer))
20632 {
20633 /* Initialize initiator wait callback */
20634 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020635 &pTdlsPeer->initiatorWaitTimeoutTimer,
20636 VOS_TIMER_TYPE_SW,
20637 wlan_hdd_tdls_initiator_wait_cb,
20638 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020639 }
Hoonki Lee14621352013-04-16 17:51:19 -070020640 wlan_hdd_tdls_timer_restart(pAdapter,
20641 &pTdlsPeer->initiatorWaitTimeoutTimer,
20642 WAIT_TIME_TDLS_INITIATOR);
20643 /* suspend initiator TX until it receives direct packet from the
20644 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020645 ret = WLANTL_SuspendDataTx(
20646 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20647 &staId, NULL);
20648 if (ret != VOS_STATUS_SUCCESS) {
20649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20650 }
Hoonki Lee14621352013-04-16 17:51:19 -070020651 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020652
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020653 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020654 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020655 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020656 suppChannelLen =
20657 tdlsLinkEstablishParams.supportedChannelsLen;
20658
20659 if ((suppChannelLen > 0) &&
20660 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20661 {
20662 tANI_U8 suppPeerChannel = 0;
20663 int i = 0;
20664 for (i = 0U; i < suppChannelLen; i++)
20665 {
20666 suppPeerChannel =
20667 tdlsLinkEstablishParams.supportedChannels[i];
20668
20669 pTdlsPeer->isOffChannelSupported = FALSE;
20670 if (suppPeerChannel ==
20671 pTdlsPeer->peerParams.channel)
20672 {
20673 pTdlsPeer->isOffChannelSupported = TRUE;
20674 break;
20675 }
20676 }
20677 }
20678 else
20679 {
20680 pTdlsPeer->isOffChannelSupported = FALSE;
20681 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020682 }
20683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20684 "%s: TDLS channel switch request for channel "
20685 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020686 "%d isOffChannelSupported %d", __func__,
20687 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020688 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020689 suppChannelLen,
20690 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020691
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020692 /* TDLS Off Channel, Enable tdls channel switch,
20693 when their is only one tdls link and it supports */
20694 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20695 if ((numCurrTdlsPeers == 1) &&
20696 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20697 (TRUE == pTdlsPeer->isOffChannelConfigured))
20698 {
20699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20700 "%s: Send TDLS channel switch request for channel %d",
20701 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020702
20703 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020704 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20705 channel = pTdlsPeer->peerParams.channel;
20706
20707 mutex_unlock(&pHddCtx->tdls_lock);
20708
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020709 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20710 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020711 peerMac,
20712 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020713 TDLS_OFF_CHANNEL_BW_OFFSET,
20714 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020715 if (ret != VOS_STATUS_SUCCESS) {
20716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20717 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020718 }
20719 else
20720 {
20721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20722 "%s: TDLS channel switch request not sent"
20723 " numCurrTdlsPeers %d "
20724 "isOffChannelSupported %d "
20725 "isOffChannelConfigured %d",
20726 __func__, numCurrTdlsPeers,
20727 pTdlsPeer->isOffChannelSupported,
20728 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020729 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020730 }
20731
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020732 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020733 else
20734 mutex_unlock(&pHddCtx->tdls_lock);
20735
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020736 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020737
20738 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020739 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20740 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020741 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020742 int ac;
20743 uint8 ucAc[4] = { WLANTL_AC_VO,
20744 WLANTL_AC_VI,
20745 WLANTL_AC_BK,
20746 WLANTL_AC_BE };
20747 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20748 for(ac=0; ac < 4; ac++)
20749 {
20750 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20751 pTdlsPeer->staId, ucAc[ac],
20752 tlTid[ac], tlTid[ac], 0, 0,
20753 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020754 if (status != VOS_STATUS_SUCCESS) {
20755 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20756 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020757 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020758 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020759 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020760
Bhargav Shah66896792015-10-01 18:17:37 +053020761 /* stop TCP delack timer if TDLS is enable */
20762 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20763 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020764 hdd_wlan_tdls_enable_link_event(peer,
20765 pTdlsPeer->isOffChannelSupported,
20766 pTdlsPeer->isOffChannelConfigured,
20767 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020768 }
20769 break;
20770 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020771 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020772 tANI_U16 numCurrTdlsPeers = 0;
20773 hddTdlsPeer_t *connPeer = NULL;
20774
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20776 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20777 __func__, MAC_ADDR_ARRAY(peer));
20778
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020779 mutex_lock(&pHddCtx->tdls_lock);
20780 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020781
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020782
Sunil Dutt41de4e22013-11-14 18:09:02 +053020783 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020784 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20786 " (oper %d) not exsting. ignored",
20787 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20788 return -EINVAL;
20789 }
20790
20791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20792 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20793 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20794 "NL80211_TDLS_DISABLE_LINK");
20795
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020796 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020797 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020798 long status;
20799
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020800 /* set tdls off channel status to false for this peer */
20801 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020802 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20803 eTDLS_LINK_TEARING,
20804 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20805 eTDLS_LINK_UNSPECIFIED:
20806 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020807 mutex_unlock(&pHddCtx->tdls_lock);
20808
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020809 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20810
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020811 status = sme_DeleteTdlsPeerSta(
20812 WLAN_HDD_GET_HAL_CTX(pAdapter),
20813 pAdapter->sessionId, peer );
20814 if (status != VOS_STATUS_SUCCESS) {
20815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20816 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020817
20818 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20819 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020820
20821 mutex_lock(&pHddCtx->tdls_lock);
20822 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20823 if ( NULL == pTdlsPeer ) {
20824 mutex_unlock(&pHddCtx->tdls_lock);
20825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20826 " peer was freed in other context",
20827 __func__, MAC_ADDR_ARRAY(peer));
20828 return -EINVAL;
20829 }
20830
Atul Mittal271a7652014-09-12 13:18:22 +053020831 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020832 eTDLS_LINK_IDLE,
20833 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020834 mutex_unlock(&pHddCtx->tdls_lock);
20835
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020836 if (status <= 0)
20837 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20839 "%s: Del station failed status %ld",
20840 __func__, status);
20841 return -EPERM;
20842 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020843
20844 /* TDLS Off Channel, Enable tdls channel switch,
20845 when their is only one tdls link and it supports */
20846 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20847 if (numCurrTdlsPeers == 1)
20848 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020849 tSirMacAddr peerMac;
20850 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020851
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020852 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020853 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020854
20855 if (connPeer == NULL) {
20856 mutex_unlock(&pHddCtx->tdls_lock);
20857 hddLog(VOS_TRACE_LEVEL_ERROR,
20858 "%s connPeer is NULL", __func__);
20859 return -EINVAL;
20860 }
20861
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020862 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20863 channel = connPeer->peerParams.channel;
20864
20865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20866 "%s: TDLS channel switch "
20867 "isOffChannelSupported %d "
20868 "isOffChannelConfigured %d "
20869 "isOffChannelEstablished %d",
20870 __func__,
20871 (connPeer ? connPeer->isOffChannelSupported : -1),
20872 (connPeer ? connPeer->isOffChannelConfigured : -1),
20873 (connPeer ? connPeer->isOffChannelEstablished : -1));
20874
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020875 if ((connPeer) &&
20876 (connPeer->isOffChannelSupported == TRUE) &&
20877 (connPeer->isOffChannelConfigured == TRUE))
20878 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020879 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020880 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020881 status = sme_SendTdlsChanSwitchReq(
20882 WLAN_HDD_GET_HAL_CTX(pAdapter),
20883 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020884 peerMac,
20885 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020886 TDLS_OFF_CHANNEL_BW_OFFSET,
20887 TDLS_CHANNEL_SWITCH_ENABLE);
20888 if (status != VOS_STATUS_SUCCESS) {
20889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20890 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020891 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020892 else
20893 mutex_unlock(&pHddCtx->tdls_lock);
20894 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020895 else
20896 {
20897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20898 "%s: TDLS channel switch request not sent "
20899 "numCurrTdlsPeers %d ",
20900 __func__, numCurrTdlsPeers);
20901 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020902 }
20903 else
20904 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020905 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20907 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020908 }
Bhargav Shah66896792015-10-01 18:17:37 +053020909 if (numCurrTdlsPeers == 0) {
20910 /* start TCP delack timer if TDLS is disable */
20911 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20912 hdd_manage_delack_timer(pHddCtx);
20913 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020914 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020915 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020916 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020917 {
Atul Mittal115287b2014-07-08 13:26:33 +053020918 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020919
Atul Mittal115287b2014-07-08 13:26:33 +053020920 if (0 != status)
20921 {
20922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020923 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020924 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020925 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020926 break;
20927 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020928 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020929 {
Atul Mittal115287b2014-07-08 13:26:33 +053020930 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20931 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020932 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020933 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020934
Atul Mittal115287b2014-07-08 13:26:33 +053020935 if (0 != status)
20936 {
20937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020938 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020939 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020940 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020941 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020942 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020943 case NL80211_TDLS_DISCOVERY_REQ:
20944 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020946 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020947 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020948 return -ENOTSUPP;
20949 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20951 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020952 return -ENOTSUPP;
20953 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020954
20955 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020956 return 0;
20957}
Chilam NG571c65a2013-01-19 12:27:36 +053020958
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020959static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020960#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20961 const u8 *peer,
20962#else
20963 u8 *peer,
20964#endif
20965 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020966{
20967 int ret;
20968
20969 vos_ssr_protect(__func__);
20970 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20971 vos_ssr_unprotect(__func__);
20972
20973 return ret;
20974}
20975
Chilam NG571c65a2013-01-19 12:27:36 +053020976int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20977 struct net_device *dev, u8 *peer)
20978{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020979 hddLog(VOS_TRACE_LEVEL_INFO,
20980 "tdls send discover req: "MAC_ADDRESS_STR,
20981 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020982#if TDLS_MGMT_VERSION2
20983 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20984 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20985#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20987 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20988 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20989#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20990 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20991 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20992#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20993 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20994 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20995#else
Chilam NG571c65a2013-01-19 12:27:36 +053020996 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20997 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020998#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020999#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021000}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021001#endif
21002
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021003#ifdef WLAN_FEATURE_GTK_OFFLOAD
21004/*
21005 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21006 * Callback rountine called upon receiving response for
21007 * get offload info
21008 */
21009void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21010 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21011{
21012
21013 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021014 tANI_U8 tempReplayCounter[8];
21015 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021016
21017 ENTER();
21018
21019 if (NULL == pAdapter)
21020 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021022 "%s: HDD adapter is Null", __func__);
21023 return ;
21024 }
21025
21026 if (NULL == pGtkOffloadGetInfoRsp)
21027 {
21028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21029 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21030 return ;
21031 }
21032
21033 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21034 {
21035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21036 "%s: wlan Failed to get replay counter value",
21037 __func__);
21038 return ;
21039 }
21040
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021041 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21042 /* Update replay counter */
21043 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21044 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21045
21046 {
21047 /* changing from little to big endian since supplicant
21048 * works on big endian format
21049 */
21050 int i;
21051 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21052
21053 for (i = 0; i < 8; i++)
21054 {
21055 tempReplayCounter[7-i] = (tANI_U8)p[i];
21056 }
21057 }
21058
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021059 /* Update replay counter to NL */
21060 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021061 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021062}
21063
21064/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021065 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021066 * This function is used to offload GTK rekeying job to the firmware.
21067 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021068int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021069 struct cfg80211_gtk_rekey_data *data)
21070{
21071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21072 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21073 hdd_station_ctx_t *pHddStaCtx;
21074 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021075 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021076 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021077 eHalStatus status = eHAL_STATUS_FAILURE;
21078
21079 ENTER();
21080
21081 if (NULL == pAdapter)
21082 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021084 "%s: HDD adapter is Null", __func__);
21085 return -ENODEV;
21086 }
21087
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21089 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21090 pAdapter->sessionId, pAdapter->device_mode));
21091
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021092 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021093 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021095 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021096 }
21097
21098 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21099 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21100 if (NULL == hHal)
21101 {
21102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21103 "%s: HAL context is Null!!!", __func__);
21104 return -EAGAIN;
21105 }
21106
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021107 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21108 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21109 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21110 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021111 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021112 {
21113 /* changing from big to little endian since driver
21114 * works on little endian format
21115 */
21116 tANI_U8 *p =
21117 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21118 int i;
21119
21120 for (i = 0; i < 8; i++)
21121 {
21122 p[7-i] = data->replay_ctr[i];
21123 }
21124 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021125
21126 if (TRUE == pHddCtx->hdd_wlan_suspended)
21127 {
21128 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021129 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21130 sizeof (tSirGtkOffloadParams));
21131 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021132 pAdapter->sessionId);
21133
21134 if (eHAL_STATUS_SUCCESS != status)
21135 {
21136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21137 "%s: sme_SetGTKOffload failed, returned %d",
21138 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021139
21140 /* Need to clear any trace of key value in the memory.
21141 * Thus zero out the memory even though it is local
21142 * variable.
21143 */
21144 vos_mem_zero(&hddGtkOffloadReqParams,
21145 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021146 return status;
21147 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21149 "%s: sme_SetGTKOffload successfull", __func__);
21150 }
21151 else
21152 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21154 "%s: wlan not suspended GTKOffload request is stored",
21155 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021156 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021157
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021158 /* Need to clear any trace of key value in the memory.
21159 * Thus zero out the memory even though it is local
21160 * variable.
21161 */
21162 vos_mem_zero(&hddGtkOffloadReqParams,
21163 sizeof(hddGtkOffloadReqParams));
21164
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021165 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021166 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021167}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021168
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021169int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21170 struct cfg80211_gtk_rekey_data *data)
21171{
21172 int ret;
21173
21174 vos_ssr_protect(__func__);
21175 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21176 vos_ssr_unprotect(__func__);
21177
21178 return ret;
21179}
21180#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021181/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021182 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021183 * This function is used to set access control policy
21184 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021185static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21186 struct net_device *dev,
21187 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021188{
21189 int i;
21190 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21191 hdd_hostapd_state_t *pHostapdState;
21192 tsap_Config_t *pConfig;
21193 v_CONTEXT_t pVosContext = NULL;
21194 hdd_context_t *pHddCtx;
21195 int status;
21196
21197 ENTER();
21198
21199 if (NULL == pAdapter)
21200 {
21201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21202 "%s: HDD adapter is Null", __func__);
21203 return -ENODEV;
21204 }
21205
21206 if (NULL == params)
21207 {
21208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21209 "%s: params is Null", __func__);
21210 return -EINVAL;
21211 }
21212
21213 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21214 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021215 if (0 != status)
21216 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021217 return status;
21218 }
21219
21220 pVosContext = pHddCtx->pvosContext;
21221 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21222
21223 if (NULL == pHostapdState)
21224 {
21225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21226 "%s: pHostapdState is Null", __func__);
21227 return -EINVAL;
21228 }
21229
21230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21231 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21233 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21234 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021235
21236 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21237 {
21238 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21239
21240 /* default value */
21241 pConfig->num_accept_mac = 0;
21242 pConfig->num_deny_mac = 0;
21243
21244 /**
21245 * access control policy
21246 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21247 * listed in hostapd.deny file.
21248 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21249 * listed in hostapd.accept file.
21250 */
21251 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21252 {
21253 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21254 }
21255 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21256 {
21257 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21258 }
21259 else
21260 {
21261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21262 "%s:Acl Policy : %d is not supported",
21263 __func__, params->acl_policy);
21264 return -ENOTSUPP;
21265 }
21266
21267 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21268 {
21269 pConfig->num_accept_mac = params->n_acl_entries;
21270 for (i = 0; i < params->n_acl_entries; i++)
21271 {
21272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21273 "** Add ACL MAC entry %i in WhiletList :"
21274 MAC_ADDRESS_STR, i,
21275 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21276
21277 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21278 sizeof(qcmacaddr));
21279 }
21280 }
21281 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21282 {
21283 pConfig->num_deny_mac = params->n_acl_entries;
21284 for (i = 0; i < params->n_acl_entries; i++)
21285 {
21286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21287 "** Add ACL MAC entry %i in BlackList :"
21288 MAC_ADDRESS_STR, i,
21289 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21290
21291 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21292 sizeof(qcmacaddr));
21293 }
21294 }
21295
21296 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21297 {
21298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21299 "%s: SAP Set Mac Acl fail", __func__);
21300 return -EINVAL;
21301 }
21302 }
21303 else
21304 {
21305 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021306 "%s: Invalid device_mode = %s (%d)",
21307 __func__, hdd_device_modetoString(pAdapter->device_mode),
21308 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021309 return -EINVAL;
21310 }
21311
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021312 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021313 return 0;
21314}
21315
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021316static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21317 struct net_device *dev,
21318 const struct cfg80211_acl_data *params)
21319{
21320 int ret;
21321 vos_ssr_protect(__func__);
21322 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21323 vos_ssr_unprotect(__func__);
21324
21325 return ret;
21326}
21327
Leo Chang9056f462013-08-01 19:21:11 -070021328#ifdef WLAN_NL80211_TESTMODE
21329#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021330void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021331(
21332 void *pAdapter,
21333 void *indCont
21334)
21335{
Leo Changd9df8aa2013-09-26 13:32:26 -070021336 tSirLPHBInd *lphbInd;
21337 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021338 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021339
21340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021341 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021342
c_hpothu73f35e62014-04-18 13:40:08 +053021343 if (pAdapter == NULL)
21344 {
21345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21346 "%s: pAdapter is NULL\n",__func__);
21347 return;
21348 }
21349
Leo Chang9056f462013-08-01 19:21:11 -070021350 if (NULL == indCont)
21351 {
21352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021353 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021354 return;
21355 }
21356
c_hpothu73f35e62014-04-18 13:40:08 +053021357 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021358 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021359 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021360 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021361 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021362 GFP_ATOMIC);
21363 if (!skb)
21364 {
21365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21366 "LPHB timeout, NL buffer alloc fail");
21367 return;
21368 }
21369
Leo Changac3ba772013-10-07 09:47:04 -070021370 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021371 {
21372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21373 "WLAN_HDD_TM_ATTR_CMD put fail");
21374 goto nla_put_failure;
21375 }
Leo Changac3ba772013-10-07 09:47:04 -070021376 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021377 {
21378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21379 "WLAN_HDD_TM_ATTR_TYPE put fail");
21380 goto nla_put_failure;
21381 }
Leo Changac3ba772013-10-07 09:47:04 -070021382 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021383 sizeof(tSirLPHBInd), lphbInd))
21384 {
21385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21386 "WLAN_HDD_TM_ATTR_DATA put fail");
21387 goto nla_put_failure;
21388 }
Leo Chang9056f462013-08-01 19:21:11 -070021389 cfg80211_testmode_event(skb, GFP_ATOMIC);
21390 return;
21391
21392nla_put_failure:
21393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21394 "NLA Put fail");
21395 kfree_skb(skb);
21396
21397 return;
21398}
21399#endif /* FEATURE_WLAN_LPHB */
21400
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021401static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021402{
21403 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21404 int err = 0;
21405#ifdef FEATURE_WLAN_LPHB
21406 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021407 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021408
21409 ENTER();
21410
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021411 err = wlan_hdd_validate_context(pHddCtx);
21412 if (0 != err)
21413 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021414 return err;
21415 }
Leo Chang9056f462013-08-01 19:21:11 -070021416#endif /* FEATURE_WLAN_LPHB */
21417
21418 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21419 if (err)
21420 {
21421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21422 "%s Testmode INV ATTR", __func__);
21423 return err;
21424 }
21425
21426 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21427 {
21428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21429 "%s Testmode INV CMD", __func__);
21430 return -EINVAL;
21431 }
21432
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021433 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21434 TRACE_CODE_HDD_CFG80211_TESTMODE,
21435 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021436 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21437 {
21438#ifdef FEATURE_WLAN_LPHB
21439 /* Low Power Heartbeat configuration request */
21440 case WLAN_HDD_TM_CMD_WLAN_HB:
21441 {
21442 int buf_len;
21443 void *buf;
21444 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021445 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021446
21447 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21448 {
21449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21450 "%s Testmode INV DATA", __func__);
21451 return -EINVAL;
21452 }
21453
21454 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21455 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021456
Manjeet Singh3c577442017-02-10 19:03:38 +053021457 if (buf_len > sizeof(*hb_params)) {
21458 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21459 buf_len);
21460 return -ERANGE;
21461 }
21462
Amar Singhal05852702014-02-04 14:40:00 -080021463 hb_params_temp =(tSirLPHBReq *)buf;
21464 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21465 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21466 return -EINVAL;
21467
Leo Chang9056f462013-08-01 19:21:11 -070021468 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21469 if (NULL == hb_params)
21470 {
21471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21472 "%s Request Buffer Alloc Fail", __func__);
21473 return -EINVAL;
21474 }
21475
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021476 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021477 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021478 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21479 hb_params,
21480 wlan_hdd_cfg80211_lphb_ind_handler);
21481 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021482 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21484 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021485 vos_mem_free(hb_params);
21486 }
Leo Chang9056f462013-08-01 19:21:11 -070021487 return 0;
21488 }
21489#endif /* FEATURE_WLAN_LPHB */
21490 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21492 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021493 return -EOPNOTSUPP;
21494 }
21495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021496 EXIT();
21497 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021498}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021499
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021500static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21501#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21502 struct wireless_dev *wdev,
21503#endif
21504 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021505{
21506 int ret;
21507
21508 vos_ssr_protect(__func__);
21509 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21510 vos_ssr_unprotect(__func__);
21511
21512 return ret;
21513}
Leo Chang9056f462013-08-01 19:21:11 -070021514#endif /* CONFIG_NL80211_TESTMODE */
21515
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021516extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021517static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021518 struct net_device *dev,
21519 int idx, struct survey_info *survey)
21520{
21521 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21522 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021523 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021524 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021525 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021526 v_S7_t snr,rssi;
21527 int status, i, j, filled = 0;
21528
21529 ENTER();
21530
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021531 if (NULL == pAdapter)
21532 {
21533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21534 "%s: HDD adapter is Null", __func__);
21535 return -ENODEV;
21536 }
21537
21538 if (NULL == wiphy)
21539 {
21540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21541 "%s: wiphy is Null", __func__);
21542 return -ENODEV;
21543 }
21544
21545 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21546 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021547 if (0 != status)
21548 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021549 return status;
21550 }
21551
Mihir Sheted9072e02013-08-21 17:02:29 +053021552 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21553
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021554 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021555 0 != pAdapter->survey_idx ||
21556 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021557 {
21558 /* The survey dump ops when implemented completely is expected to
21559 * return a survey of all channels and the ops is called by the
21560 * kernel with incremental values of the argument 'idx' till it
21561 * returns -ENONET. But we can only support the survey for the
21562 * operating channel for now. survey_idx is used to track
21563 * that the ops is called only once and then return -ENONET for
21564 * the next iteration
21565 */
21566 pAdapter->survey_idx = 0;
21567 return -ENONET;
21568 }
21569
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021570 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21571 {
21572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21573 "%s: Roaming in progress, hence return ", __func__);
21574 return -ENONET;
21575 }
21576
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021577 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21578
21579 wlan_hdd_get_snr(pAdapter, &snr);
21580 wlan_hdd_get_rssi(pAdapter, &rssi);
21581
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021582 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21583 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21584 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021585 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21586 hdd_wlan_get_freq(channel, &freq);
21587
21588
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021589 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021590 {
21591 if (NULL == wiphy->bands[i])
21592 {
21593 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21594 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21595 continue;
21596 }
21597
21598 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21599 {
21600 struct ieee80211_supported_band *band = wiphy->bands[i];
21601
21602 if (band->channels[j].center_freq == (v_U16_t)freq)
21603 {
21604 survey->channel = &band->channels[j];
21605 /* The Rx BDs contain SNR values in dB for the received frames
21606 * while the supplicant expects noise. So we calculate and
21607 * return the value of noise (dBm)
21608 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21609 */
21610 survey->noise = rssi - snr;
21611 survey->filled = SURVEY_INFO_NOISE_DBM;
21612 filled = 1;
21613 }
21614 }
21615 }
21616
21617 if (filled)
21618 pAdapter->survey_idx = 1;
21619 else
21620 {
21621 pAdapter->survey_idx = 0;
21622 return -ENONET;
21623 }
21624
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021625 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021626 return 0;
21627}
21628
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021629static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21630 struct net_device *dev,
21631 int idx, struct survey_info *survey)
21632{
21633 int ret;
21634
21635 vos_ssr_protect(__func__);
21636 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21637 vos_ssr_unprotect(__func__);
21638
21639 return ret;
21640}
21641
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021642/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021643 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021644 * this is called when cfg80211 driver resume
21645 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21646 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021647int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021648{
21649 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21650 hdd_adapter_t *pAdapter;
21651 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21652 VOS_STATUS status = VOS_STATUS_SUCCESS;
21653
21654 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021655
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021656 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021657 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021658 return 0;
21659 }
21660
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021661 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21662 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021663
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021664 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021665 {
21666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21667 "%s: Resume SoftAP", __func__);
21668 hdd_set_wlan_suspend_mode(false);
21669 }
21670
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021671 spin_lock(&pHddCtx->schedScan_lock);
21672 pHddCtx->isWiphySuspended = FALSE;
21673 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21674 {
21675 spin_unlock(&pHddCtx->schedScan_lock);
21676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21677 "%s: Return resume is not due to PNO indication", __func__);
21678 return 0;
21679 }
21680 // Reset flag to avoid updatating cfg80211 data old results again
21681 pHddCtx->isSchedScanUpdatePending = FALSE;
21682 spin_unlock(&pHddCtx->schedScan_lock);
21683
21684 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21685
21686 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21687 {
21688 pAdapter = pAdapterNode->pAdapter;
21689 if ( (NULL != pAdapter) &&
21690 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21691 {
21692 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021693 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21695 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021696 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021697 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021698 {
21699 /* Acquire wakelock to handle the case where APP's tries to
21700 * suspend immediately after updating the scan results. Whis
21701 * results in app's is in suspended state and not able to
21702 * process the connect request to AP
21703 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021704 hdd_prevent_suspend_timeout(2000,
21705 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021706 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021707 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021708
21709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21710 "%s : cfg80211 scan result database updated", __func__);
21711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021712 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021713 return 0;
21714
21715 }
21716 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21717 pAdapterNode = pNext;
21718 }
21719
21720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21721 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021722 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021723 return 0;
21724}
21725
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021726int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21727{
21728 int ret;
21729
21730 vos_ssr_protect(__func__);
21731 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21732 vos_ssr_unprotect(__func__);
21733
21734 return ret;
21735}
21736
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021737/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021738 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021739 * this is called when cfg80211 driver suspends
21740 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021741int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021742 struct cfg80211_wowlan *wow)
21743{
21744 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021745 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021746
21747 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021748
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021749 ret = wlan_hdd_validate_context(pHddCtx);
21750 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021751 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021752 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021753 }
21754
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021755 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21757 "%s: Suspend SoftAP", __func__);
21758 hdd_set_wlan_suspend_mode(true);
21759 }
21760
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021761
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021762 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21763 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21764 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021765 pHddCtx->isWiphySuspended = TRUE;
21766
21767 EXIT();
21768
21769 return 0;
21770}
21771
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021772int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21773 struct cfg80211_wowlan *wow)
21774{
21775 int ret;
21776
21777 vos_ssr_protect(__func__);
21778 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21779 vos_ssr_unprotect(__func__);
21780
21781 return ret;
21782}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021783
21784#ifdef FEATURE_OEM_DATA_SUPPORT
21785static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021786 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021787{
21788 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21789
21790 ENTER();
21791
21792 if (wlan_hdd_validate_context(pHddCtx)) {
21793 return;
21794 }
21795 if (!pMsg)
21796 {
21797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21798 return;
21799 }
21800
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021801 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021802
21803 EXIT();
21804 return;
21805
21806}
21807
21808void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021809 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021810{
21811 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21812
21813 ENTER();
21814
21815 if (wlan_hdd_validate_context(pHddCtx)) {
21816 return;
21817 }
21818
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021820
21821 switch(evType) {
21822 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021823 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021824 break;
21825 default:
21826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21827 break;
21828 }
21829 EXIT();
21830}
21831#endif
21832
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021833#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21834 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021835/**
21836 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21837 * @wiphy: Pointer to wiphy
21838 * @wdev: Pointer to wireless device structure
21839 *
21840 * This function is used to abort an ongoing scan
21841 *
21842 * Return: None
21843 */
21844static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21845 struct wireless_dev *wdev)
21846{
21847 struct net_device *dev = wdev->netdev;
21848 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21849 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21850 int ret;
21851
21852 ENTER();
21853
21854 if (NULL == adapter) {
21855 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21856 return;
21857 }
21858
21859 ret = wlan_hdd_validate_context(hdd_ctx);
21860 if (0 != ret)
21861 return;
21862
21863 wlan_hdd_scan_abort(adapter);
21864
21865 return;
21866}
21867
21868/**
21869 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21870 * @wiphy: Pointer to wiphy
21871 * @wdev: Pointer to wireless device structure
21872 *
21873 * Return: None
21874 */
21875void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21876 struct wireless_dev *wdev)
21877{
21878 vos_ssr_protect(__func__);
21879 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21880 vos_ssr_unprotect(__func__);
21881
21882 return;
21883}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021884#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021885
Abhishek Singh936c6932017-11-07 17:28:23 +053021886#ifdef CHANNEL_SWITCH_SUPPORTED
21887/**
21888 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21889 * channel in SAP/GO
21890 * @wiphy: wiphy pointer
21891 * @dev: dev pointer.
21892 * @csa_params: Change channel params
21893 *
21894 * This function is called to switch channel in SAP/GO
21895 *
21896 * Return: 0 if success else return non zero
21897 */
21898static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21899 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21900{
21901 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21902 hdd_context_t *hdd_ctx;
21903 uint8_t channel;
21904 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021905 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053021906 v_CONTEXT_t vos_ctx;
21907
21908 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21909
21910 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21911 ret = wlan_hdd_validate_context(hdd_ctx);
21912 if (ret)
21913 return ret;
21914
21915 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21916 if (!vos_ctx) {
21917 hddLog(LOGE, FL("Vos ctx is null"));
21918 return -EINVAL;
21919 }
21920
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021921 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053021922 return -ENOTSUPP;
21923
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021924 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
21925 if (!sap_ctx) {
21926 hddLog(LOGE, FL("sap_ctx is NULL"));
21927 return -EINVAL;
21928 }
21929
21930 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
21931 if (ret)
21932 return ret;
21933
21934 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
21935
Abhishek Singh936c6932017-11-07 17:28:23 +053021936 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021937 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021938
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021939 if (ret) {
21940 wlansap_reset_chan_change_in_progress(sap_ctx);
21941 complete(&sap_ctx->ecsa_info.chan_switch_comp);
21942 }
21943
Abhishek Singh936c6932017-11-07 17:28:23 +053021944 return ret;
21945}
21946
21947/**
21948 * wlan_hdd_cfg80211_channel_switch()- function to switch
21949 * channel in SAP/GO
21950 * @wiphy: wiphy pointer
21951 * @dev: dev pointer.
21952 * @csa_params: Change channel params
21953 *
21954 * This function is called to switch channel in SAP/GO
21955 *
21956 * Return: 0 if success else return non zero
21957 */
21958static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21959 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21960{
21961 int ret;
21962
21963 vos_ssr_protect(__func__);
21964 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21965 vos_ssr_unprotect(__func__);
21966
21967 return ret;
21968}
21969#endif
21970
Jeff Johnson295189b2012-06-20 16:38:30 -070021971/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021972static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021973{
21974 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21975 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21976 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21977 .change_station = wlan_hdd_change_station,
21978#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21979 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21980 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21981 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021982#else
21983 .start_ap = wlan_hdd_cfg80211_start_ap,
21984 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21985 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021986#endif
21987 .change_bss = wlan_hdd_cfg80211_change_bss,
21988 .add_key = wlan_hdd_cfg80211_add_key,
21989 .get_key = wlan_hdd_cfg80211_get_key,
21990 .del_key = wlan_hdd_cfg80211_del_key,
21991 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021992#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021993 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021994#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021995 .scan = wlan_hdd_cfg80211_scan,
21996 .connect = wlan_hdd_cfg80211_connect,
21997 .disconnect = wlan_hdd_cfg80211_disconnect,
21998 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21999 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22000 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22001 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22002 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022003 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22004 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022005 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22007 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22008 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22009 .set_txq_params = wlan_hdd_set_txq_params,
22010#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022011 .get_station = wlan_hdd_cfg80211_get_station,
22012 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22013 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022014 .add_station = wlan_hdd_cfg80211_add_station,
22015#ifdef FEATURE_WLAN_LFR
22016 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22017 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22018 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22019#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022020#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22021 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22022#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022023#ifdef FEATURE_WLAN_TDLS
22024 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22025 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22026#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022027#ifdef WLAN_FEATURE_GTK_OFFLOAD
22028 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22029#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022030#ifdef FEATURE_WLAN_SCAN_PNO
22031 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22032 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22033#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022034 .resume = wlan_hdd_cfg80211_resume_wlan,
22035 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022036 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022037#ifdef WLAN_NL80211_TESTMODE
22038 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22039#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022040 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22042 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022043 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022044#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022045#ifdef CHANNEL_SWITCH_SUPPORTED
22046 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22047#endif
22048
Jeff Johnson295189b2012-06-20 16:38:30 -070022049};
22050