blob: c955cae2fc8d7625cd578ccf3ca4b8e2d20dc306 [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/*
655 * FUNCTION: __wlan_hdd_cfg80211_nan_request
656 * This is called when wlan driver needs to send vendor specific
657 * nan request event.
658 */
659static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
660 struct wireless_dev *wdev,
661 const void *data, int data_len)
662{
663 tNanRequestReq nan_req;
664 VOS_STATUS status;
665 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530666 struct net_device *dev = wdev->netdev;
667 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
668 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530669 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
670
671 if (0 == data_len)
672 {
673 hddLog(VOS_TRACE_LEVEL_ERROR,
674 FL("NAN - Invalid Request, length = 0"));
675 return ret_val;
676 }
677
678 if (NULL == data)
679 {
680 hddLog(VOS_TRACE_LEVEL_ERROR,
681 FL("NAN - Invalid Request, data is NULL"));
682 return ret_val;
683 }
684
685 status = wlan_hdd_validate_context(pHddCtx);
686 if (0 != status)
687 {
688 hddLog(VOS_TRACE_LEVEL_ERROR,
689 FL("HDD context is not valid"));
690 return -EINVAL;
691 }
692
693 hddLog(LOG1, FL("Received NAN command"));
694 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 (tANI_U8 *)data, data_len);
696
697 /* check the NAN Capability */
698 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
699 {
700 hddLog(VOS_TRACE_LEVEL_ERROR,
701 FL("NAN is not supported by Firmware"));
702 return -EINVAL;
703 }
704
705 nan_req.request_data_len = data_len;
706 nan_req.request_data = data;
707
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530708 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530709 if (VOS_STATUS_SUCCESS == status)
710 {
711 ret_val = 0;
712 }
713 return ret_val;
714}
715
716/*
717 * FUNCTION: wlan_hdd_cfg80211_nan_request
718 * Wrapper to protect the nan vendor command from ssr
719 */
720static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
721 struct wireless_dev *wdev,
722 const void *data, int data_len)
723{
724 int ret;
725
726 vos_ssr_protect(__func__);
727 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
728 vos_ssr_unprotect(__func__);
729
730 return ret;
731}
732
733/*
734 * FUNCTION: wlan_hdd_cfg80211_nan_callback
735 * This is a callback function and it gets called
736 * when we need to report nan response event to
737 * upper layers.
738 */
739static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
740{
741 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
742 struct sk_buff *vendor_event;
743 int status;
744 tSirNanEvent *data;
745
746 ENTER();
747 if (NULL == msg)
748 {
749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
750 FL(" msg received here is null"));
751 return;
752 }
753 data = msg;
754
755 status = wlan_hdd_validate_context(pHddCtx);
756
757 if (0 != status)
758 {
759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
760 FL("HDD context is not valid"));
761 return;
762 }
763
764 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530765#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
766 NULL,
767#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530768 data->event_data_len +
769 NLMSG_HDRLEN,
770 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
771 GFP_KERNEL);
772
773 if (!vendor_event)
774 {
775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
776 FL("cfg80211_vendor_event_alloc failed"));
777 return;
778 }
779 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
780 data->event_data_len, data->event_data))
781 {
782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
783 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
784 kfree_skb(vendor_event);
785 return;
786 }
787 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
788 EXIT();
789}
790
791/*
792 * FUNCTION: wlan_hdd_cfg80211_nan_init
793 * This function is called to register the callback to sme layer
794 */
795inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
796{
797 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
798}
799
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530800/*
801 * define short names for the global vendor params
802 * used by __wlan_hdd_cfg80211_get_station_cmd()
803 */
804#define STATION_INVALID \
805 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
806#define STATION_INFO \
807 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
808#define STATION_ASSOC_FAIL_REASON \
809 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530810#define STATION_REMOTE \
811 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530812#define STATION_MAX \
813 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
814
815static const struct nla_policy
816hdd_get_station_policy[STATION_MAX + 1] = {
817 [STATION_INFO] = {.type = NLA_FLAG},
818 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
819};
820
821/**
822 * hdd_get_station_assoc_fail() - Handle get station assoc fail
823 * @hdd_ctx: HDD context within host driver
824 * @wdev: wireless device
825 *
826 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
827 * Validate cmd attributes and send the station info to upper layers.
828 *
829 * Return: Success(0) or reason code for failure
830 */
831static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
832 hdd_adapter_t *adapter)
833{
834 struct sk_buff *skb = NULL;
835 uint32_t nl_buf_len;
836 hdd_station_ctx_t *hdd_sta_ctx;
837
838 nl_buf_len = NLMSG_HDRLEN;
839 nl_buf_len += sizeof(uint32_t);
840 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
841
842 if (!skb) {
843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
844 return -ENOMEM;
845 }
846
847 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
848
849 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
850 hdd_sta_ctx->conn_info.assoc_status_code)) {
851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
852 goto fail;
853 }
854 return cfg80211_vendor_cmd_reply(skb);
855fail:
856 if (skb)
857 kfree_skb(skb);
858 return -EINVAL;
859}
860
861/**
862 * hdd_map_auth_type() - transform auth type specific to
863 * vendor command
864 * @auth_type: csr auth type
865 *
866 * Return: Success(0) or reason code for failure
867 */
868static int hdd_convert_auth_type(uint32_t auth_type)
869{
870 uint32_t ret_val;
871
872 switch (auth_type) {
873 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
874 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
875 break;
876 case eCSR_AUTH_TYPE_SHARED_KEY:
877 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
878 break;
879 case eCSR_AUTH_TYPE_WPA:
880 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
881 break;
882 case eCSR_AUTH_TYPE_WPA_PSK:
883 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
884 break;
885 case eCSR_AUTH_TYPE_AUTOSWITCH:
886 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
887 break;
888 case eCSR_AUTH_TYPE_WPA_NONE:
889 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
890 break;
891 case eCSR_AUTH_TYPE_RSN:
892 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
893 break;
894 case eCSR_AUTH_TYPE_RSN_PSK:
895 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
896 break;
897 case eCSR_AUTH_TYPE_FT_RSN:
898 ret_val = QCA_WLAN_AUTH_TYPE_FT;
899 break;
900 case eCSR_AUTH_TYPE_FT_RSN_PSK:
901 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
902 break;
903 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
904 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
905 break;
906 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
907 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
908 break;
909#ifdef FEATURE_WLAN_ESE
910 case eCSR_AUTH_TYPE_CCKM_WPA:
911 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
912 break;
913 case eCSR_AUTH_TYPE_CCKM_RSN:
914 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
915 break;
916#endif
917 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
918 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
919 break;
920 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
921 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
922 break;
923 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
924 case eCSR_AUTH_TYPE_FAILED:
925 case eCSR_AUTH_TYPE_NONE:
926 default:
927 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
928 break;
929 }
930 return ret_val;
931}
932
933/**
934 * hdd_map_dot_11_mode() - transform dot11mode type specific to
935 * vendor command
936 * @dot11mode: dot11mode
937 *
938 * Return: Success(0) or reason code for failure
939 */
940static int hdd_convert_dot11mode(uint32_t dot11mode)
941{
942 uint32_t ret_val;
943
944 switch (dot11mode) {
945 case eCSR_CFG_DOT11_MODE_11A:
946 ret_val = QCA_WLAN_802_11_MODE_11A;
947 break;
948 case eCSR_CFG_DOT11_MODE_11B:
949 ret_val = QCA_WLAN_802_11_MODE_11B;
950 break;
951 case eCSR_CFG_DOT11_MODE_11G:
952 ret_val = QCA_WLAN_802_11_MODE_11G;
953 break;
954 case eCSR_CFG_DOT11_MODE_11N:
955 ret_val = QCA_WLAN_802_11_MODE_11N;
956 break;
957 case eCSR_CFG_DOT11_MODE_11AC:
958 ret_val = QCA_WLAN_802_11_MODE_11AC;
959 break;
960 case eCSR_CFG_DOT11_MODE_AUTO:
961 case eCSR_CFG_DOT11_MODE_ABG:
962 default:
963 ret_val = QCA_WLAN_802_11_MODE_INVALID;
964 }
965 return ret_val;
966}
967
968/**
969 * hdd_add_tx_bitrate() - add tx bitrate attribute
970 * @skb: pointer to sk buff
971 * @hdd_sta_ctx: pointer to hdd station context
972 * @idx: attribute index
973 *
974 * Return: Success(0) or reason code for failure
975 */
976static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
977 hdd_station_ctx_t *hdd_sta_ctx,
978 int idx)
979{
980 struct nlattr *nla_attr;
981 uint32_t bitrate, bitrate_compat;
982
983 nla_attr = nla_nest_start(skb, idx);
984 if (!nla_attr)
985 goto fail;
986 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +0530987 bitrate = cfg80211_calculate_bitrate(
988 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530989
990 /* report 16-bit bitrate only if we can */
991 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
992 if (bitrate > 0 &&
993 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
995 goto fail;
996 }
997 if (bitrate_compat > 0 &&
998 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1000 goto fail;
1001 }
1002 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301003 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1005 goto fail;
1006 }
1007 nla_nest_end(skb, nla_attr);
1008 return 0;
1009fail:
1010 return -EINVAL;
1011}
1012
1013/**
1014 * hdd_add_sta_info() - add station info attribute
1015 * @skb: pointer to sk buff
1016 * @hdd_sta_ctx: pointer to hdd station context
1017 * @idx: attribute index
1018 *
1019 * Return: Success(0) or reason code for failure
1020 */
1021static int32_t hdd_add_sta_info(struct sk_buff *skb,
1022 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1023{
1024 struct nlattr *nla_attr;
1025
1026 nla_attr = nla_nest_start(skb, idx);
1027 if (!nla_attr)
1028 goto fail;
1029 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301030 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1032 goto fail;
1033 }
1034 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1035 goto fail;
1036 nla_nest_end(skb, nla_attr);
1037 return 0;
1038fail:
1039 return -EINVAL;
1040}
1041
1042/**
1043 * hdd_add_survey_info() - add survey info attribute
1044 * @skb: pointer to sk buff
1045 * @hdd_sta_ctx: pointer to hdd station context
1046 * @idx: attribute index
1047 *
1048 * Return: Success(0) or reason code for failure
1049 */
1050static int32_t hdd_add_survey_info(struct sk_buff *skb,
1051 hdd_station_ctx_t *hdd_sta_ctx,
1052 int idx)
1053{
1054 struct nlattr *nla_attr;
1055
1056 nla_attr = nla_nest_start(skb, idx);
1057 if (!nla_attr)
1058 goto fail;
1059 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301060 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301061 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301062 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1064 goto fail;
1065 }
1066 nla_nest_end(skb, nla_attr);
1067 return 0;
1068fail:
1069 return -EINVAL;
1070}
1071
1072/**
1073 * hdd_add_link_standard_info() - add link info attribute
1074 * @skb: pointer to sk buff
1075 * @hdd_sta_ctx: pointer to hdd station context
1076 * @idx: attribute index
1077 *
1078 * Return: Success(0) or reason code for failure
1079 */
1080static int32_t
1081hdd_add_link_standard_info(struct sk_buff *skb,
1082 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1083{
1084 struct nlattr *nla_attr;
1085
1086 nla_attr = nla_nest_start(skb, idx);
1087 if (!nla_attr)
1088 goto fail;
1089 if (nla_put(skb,
1090 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301091 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1092 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1094 goto fail;
1095 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301096 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1097 hdd_sta_ctx->cache_conn_info.bssId))
1098 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301099 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1100 goto fail;
1101 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1102 goto fail;
1103 nla_nest_end(skb, nla_attr);
1104 return 0;
1105fail:
1106 return -EINVAL;
1107}
1108
1109/**
1110 * hdd_add_ap_standard_info() - add ap info attribute
1111 * @skb: pointer to sk buff
1112 * @hdd_sta_ctx: pointer to hdd station context
1113 * @idx: attribute index
1114 *
1115 * Return: Success(0) or reason code for failure
1116 */
1117static int32_t
1118hdd_add_ap_standard_info(struct sk_buff *skb,
1119 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1120{
1121 struct nlattr *nla_attr;
1122
1123 nla_attr = nla_nest_start(skb, idx);
1124 if (!nla_attr)
1125 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301126 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301127 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301128 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1129 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1131 goto fail;
1132 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301133 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301134 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301135 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1136 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1138 goto fail;
1139 }
1140 nla_nest_end(skb, nla_attr);
1141 return 0;
1142fail:
1143 return -EINVAL;
1144}
1145
1146/**
1147 * hdd_get_station_info() - send BSS information to supplicant
1148 * @hdd_ctx: pointer to hdd context
1149 * @adapter: pointer to adapter
1150 *
1151 * Return: 0 if success else error status
1152 */
1153static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1154 hdd_adapter_t *adapter)
1155{
1156 struct sk_buff *skb = NULL;
1157 uint8_t *tmp_hs20 = NULL;
1158 uint32_t nl_buf_len;
1159 hdd_station_ctx_t *hdd_sta_ctx;
1160
1161 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1162
1163 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301164
1165 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1166 VOS_MAC_ADDR_SIZE +
1167 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1168 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1169 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301170 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301171 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1172 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1173 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1174 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1175 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1176 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1177 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1178 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1179 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1180 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1181 cache_conn_info.hs20vendor_ie);
1182 nl_buf_len +=
1183 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301184 1);
1185 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301186 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1187 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1188 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1189 nl_buf_len +=
1190 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301191
1192
1193 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1194 if (!skb) {
1195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1196 __func__, __LINE__);
1197 return -ENOMEM;
1198 }
1199
1200 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1201 LINK_INFO_STANDARD_NL80211_ATTR)) {
1202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1203 goto fail;
1204 }
1205 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1206 AP_INFO_STANDARD_NL80211_ATTR)) {
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1208 goto fail;
1209 }
1210 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301211 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301212 nla_put_u32(skb, INFO_AKM,
1213 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301214 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301215 nla_put_u32(skb, WLAN802_11_MODE,
1216 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301217 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1219 goto fail;
1220 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301221 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301222 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301223 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1224 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
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.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301229 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 (sizeof(hdd_sta_ctx->
1231 cache_conn_info.vht_operation)),
1232 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1234 goto fail;
1235 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301236 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301237 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301238 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1239 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1241 goto fail;
1242 }
1243
1244 return cfg80211_vendor_cmd_reply(skb);
1245fail:
1246 if (skb)
1247 kfree_skb(skb);
1248 return -EINVAL;
1249}
1250
1251/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301252 * hdd_add_survey_info_sap_get_len - get data length used in
1253 * hdd_add_survey_info_sap()
1254 *
1255 * This function calculates the data length used in hdd_add_survey_info_sap()
1256 *
1257 * Return: total data length used in hdd_add_survey_info_sap()
1258 */
1259static uint32_t hdd_add_survey_info_sap_get_len(void)
1260{
1261 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1262}
1263
1264/**
1265 * hdd_add_survey_info - add survey info attribute
1266 * @skb: pointer to response skb buffer
1267 * @stainfo: station information
1268 * @idx: attribute type index for nla_next_start()
1269 *
1270 * This function adds survey info attribute to response skb buffer
1271 *
1272 * Return : 0 on success and errno on failure
1273 */
1274static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1275 struct hdd_cache_sta_info *stainfo,
1276 int idx)
1277{
1278 struct nlattr *nla_attr;
1279
1280 nla_attr = nla_nest_start(skb, idx);
1281 if (!nla_attr)
1282 goto fail;
1283 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1284 stainfo->freq)) {
1285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1286 FL("put fail"));
1287 goto fail;
1288 }
1289 nla_nest_end(skb, nla_attr);
1290 return 0;
1291fail:
1292 return -EINVAL;
1293}
1294
1295/**
1296 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1297 * hdd_add_tx_bitrate_sap()
1298 *
1299 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1300 *
1301 * Return: total data length used in hdd_add_tx_bitrate_sap()
1302 */
1303static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1304{
1305 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1306}
1307
1308/**
1309 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1310 * @skb: pointer to response skb buffer
1311 * @stainfo: station information
1312 * @idx: attribute type index for nla_next_start()
1313 *
1314 * This function adds vht nss attribute to response skb buffer
1315 *
1316 * Return : 0 on success and errno on failure
1317 */
1318static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1319 struct hdd_cache_sta_info *stainfo,
1320 int idx)
1321{
1322 struct nlattr *nla_attr;
1323
1324 nla_attr = nla_nest_start(skb, idx);
1325 if (!nla_attr)
1326 goto fail;
1327
1328 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1329 stainfo->nss)) {
1330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1331 FL("put fail"));
1332 goto fail;
1333 }
1334 nla_nest_end(skb, nla_attr);
1335 return 0;
1336fail:
1337 return -EINVAL;
1338}
1339
1340/**
1341 * hdd_add_sta_info_sap_get_len - get data length used in
1342 * hdd_add_sta_info_sap()
1343 *
1344 * This function calculates the data length used in hdd_add_sta_info_sap()
1345 *
1346 * Return: total data length used in hdd_add_sta_info_sap()
1347 */
1348static uint32_t hdd_add_sta_info_sap_get_len(void)
1349{
1350 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1351 hdd_add_tx_bitrate_sap_get_len());
1352}
1353
1354/**
1355 * hdd_add_sta_info_sap - add sta signal info attribute
1356 * @skb: pointer to response skb buffer
1357 * @rssi: peer rssi value
1358 * @stainfo: station information
1359 * @idx: attribute type index for nla_next_start()
1360 *
1361 * This function adds sta signal attribute to response skb buffer
1362 *
1363 * Return : 0 on success and errno on failure
1364 */
1365static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1366 struct hdd_cache_sta_info *stainfo, int idx)
1367{
1368 struct nlattr *nla_attr;
1369
1370 nla_attr = nla_nest_start(skb, idx);
1371 if (!nla_attr)
1372 goto fail;
1373
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301374 /* upperlayer expects positive rssi value */
1375 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1377 FL("put fail"));
1378 goto fail;
1379 }
1380 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1382 FL("put fail"));
1383 goto fail;
1384 }
1385
1386 nla_nest_end(skb, nla_attr);
1387 return 0;
1388fail:
1389 return -EINVAL;
1390}
1391
1392/**
1393 * hdd_add_link_standard_info_sap_get_len - get data length used in
1394 * hdd_add_link_standard_info_sap()
1395 *
1396 * This function calculates the data length used in
1397 * hdd_add_link_standard_info_sap()
1398 *
1399 * Return: total data length used in hdd_add_link_standard_info_sap()
1400 */
1401static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1402{
1403 return ((NLA_HDRLEN) +
1404 hdd_add_survey_info_sap_get_len() +
1405 hdd_add_sta_info_sap_get_len() +
1406 (sizeof(uint32_t) + NLA_HDRLEN));
1407}
1408
1409/**
1410 * hdd_add_link_standard_info_sap - add add link info attribut
1411 * @skb: pointer to response skb buffer
1412 * @stainfo: station information
1413 * @idx: attribute type index for nla_next_start()
1414 *
1415 * This function adds link info attribut to response skb buffer
1416 *
1417 * Return : 0 on success and errno on failure
1418 */
1419static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1420 struct hdd_cache_sta_info *stainfo,
1421 int idx)
1422{
1423 struct nlattr *nla_attr;
1424
1425 nla_attr = nla_nest_start(skb, idx);
1426 if (!nla_attr)
1427 goto fail;
1428 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1429 goto fail;
1430 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1431 goto fail;
1432
1433 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1434 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1435 FL("put fail"));
1436 goto fail;
1437 }
1438
1439 nla_nest_end(skb, nla_attr);
1440 return 0;
1441fail:
1442 return -EINVAL;
1443}
1444
1445/**
1446 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1447 * hdd_add_ap_standard_info_sap()
1448 * @stainfo: station information
1449 *
1450 * This function calculates the data length used in
1451 * hdd_add_ap_standard_info_sap()
1452 *
1453 * Return: total data length used in hdd_add_ap_standard_info_sap()
1454 */
1455static uint32_t hdd_add_ap_standard_info_sap_get_len(
1456 struct hdd_cache_sta_info *stainfo)
1457{
1458 uint32_t len;
1459
1460 len = NLA_HDRLEN;
1461 if (stainfo->vht_present)
1462 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1463 if (stainfo->ht_present)
1464 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1465
1466 return len;
1467}
1468
1469/**
1470 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1471 * @skb: pointer to response skb buffer
1472 * @stainfo: station information
1473 * @idx: attribute type index for nla_next_start()
1474 *
1475 * This function adds HT and VHT info attributes to response skb buffer
1476 *
1477 * Return : 0 on success and errno on failure
1478 */
1479static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1480 struct hdd_cache_sta_info *stainfo,
1481 int idx)
1482{
1483 struct nlattr *nla_attr;
1484
1485 nla_attr = nla_nest_start(skb, idx);
1486 if (!nla_attr)
1487 goto fail;
1488
1489 if (stainfo->vht_present) {
1490 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1491 sizeof(stainfo->vht_caps),
1492 &stainfo->vht_caps)) {
1493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1494 FL("put fail"));
1495 goto fail;
1496 }
1497 }
1498 if (stainfo->ht_present) {
1499 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1500 sizeof(stainfo->ht_caps),
1501 &stainfo->ht_caps)) {
1502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1503 FL("put fail"));
1504 goto fail;
1505 }
1506 }
1507 nla_nest_end(skb, nla_attr);
1508 return 0;
1509fail:
1510 return -EINVAL;
1511}
1512
1513/**
1514 * hdd_decode_ch_width - decode channel band width based
1515 * @ch_width: encoded enum value holding channel band width
1516 *
1517 * This function decodes channel band width from the given encoded enum value.
1518 *
1519 * Returns: decoded channel band width.
1520 */
1521static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1522{
1523 switch (ch_width) {
1524 case 0:
1525 return 20;
1526 case 1:
1527 return 40;
1528 case 2:
1529 return 80;
1530 default:
1531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1532 "invalid enum: %d", ch_width);
1533 return 20;
1534 }
1535}
1536
1537/**
1538 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1539 * @hdd_ctx: hdd context
1540 * @adapter: hostapd interface
1541 * @mac_addr: mac address of requested peer
1542 *
1543 * This function collect and indicate the cached(deleted) peer's info
1544 *
1545 * Return: 0 on success, otherwise error value
1546 */
1547static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1548 hdd_adapter_t *adapter,
1549 v_MACADDR_t mac_addr)
1550{
1551 struct hdd_cache_sta_info *stainfo;
1552 struct sk_buff *skb = NULL;
1553 uint32_t nl_buf_len;
1554 uint8_t cw;
1555 ptSapContext sap_ctx;
1556 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1557
1558 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1559 if(sap_ctx == NULL){
1560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 FL("psapCtx is NULL"));
1562 return -ENOENT;
1563 }
1564
1565 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1566 mac_addr.bytes);
1567 if (!stainfo) {
1568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1569 "peer " MAC_ADDRESS_STR " not found",
1570 MAC_ADDR_ARRAY(mac_addr.bytes));
1571 return -EINVAL;
1572 }
1573 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1575 "peer " MAC_ADDRESS_STR " is in connected state",
1576 MAC_ADDR_ARRAY(mac_addr.bytes));
1577 return -EINVAL;
1578 }
1579
1580
1581 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1582 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1583 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1584 (sizeof(cw) + NLA_HDRLEN) +
1585 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1586
1587 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1588 if (!skb) {
1589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1590 return -ENOMEM;
1591 }
1592
1593 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1594 LINK_INFO_STANDARD_NL80211_ATTR)) {
1595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1596 goto fail;
1597 }
1598
1599 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1600 AP_INFO_STANDARD_NL80211_ATTR)) {
1601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1602 goto fail;
1603 }
1604
1605 /* upper layer expects decoded channel BW */
1606 cw = hdd_decode_ch_width(stainfo->ch_width);
1607 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1608 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1610 goto fail;
1611 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301612 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1614 goto fail;
1615 }
1616
1617 vos_mem_zero(stainfo, sizeof(*stainfo));
1618
1619 return cfg80211_vendor_cmd_reply(skb);
1620fail:
1621 if (skb)
1622 kfree_skb(skb);
1623
1624 return -EINVAL;
1625}
1626
1627/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301628 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1629 * @wiphy: corestack handler
1630 * @wdev: wireless device
1631 * @data: data
1632 * @data_len: data length
1633 *
1634 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1635 * Validate cmd attributes and send the station info to upper layers.
1636 *
1637 * Return: Success(0) or reason code for failure
1638 */
1639static int32_t
1640__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1641 struct wireless_dev *wdev,
1642 const void *data,
1643 int data_len)
1644{
1645 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1646 struct net_device *dev = wdev->netdev;
1647 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1648 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1649 int32_t status;
1650
1651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1652 if (VOS_FTM_MODE == hdd_get_conparam()) {
1653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1654 status = -EPERM;
1655 goto out;
1656 }
1657
1658 status = wlan_hdd_validate_context(hdd_ctx);
1659 if (0 != status)
1660 goto out;
1661
1662
1663 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1664 data, data_len, NULL);
1665 if (status) {
1666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1667 goto out;
1668 }
1669
1670 /* Parse and fetch Command Type*/
1671 if (tb[STATION_INFO]) {
1672 status = hdd_get_station_info(hdd_ctx, adapter);
1673 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1674 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301675 } else if (tb[STATION_REMOTE]) {
1676 v_MACADDR_t mac_addr;
1677
1678 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1679 adapter->device_mode != WLAN_HDD_P2P_GO) {
1680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1681 adapter->device_mode);
1682 status = -EINVAL;
1683 goto out;
1684 }
1685
1686 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1687 VOS_MAC_ADDRESS_LEN);
1688
1689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1690 MAC_ADDR_ARRAY(mac_addr.bytes));
1691
1692 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1693 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301694 } else {
1695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1696 status = -EINVAL;
1697 goto out;
1698 }
1699 EXIT();
1700out:
1701 return status;
1702}
1703
1704/**
1705 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1706 * @wiphy: corestack handler
1707 * @wdev: wireless device
1708 * @data: data
1709 * @data_len: data length
1710 *
1711 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1712 * Validate cmd attributes and send the station info to upper layers.
1713 *
1714 * Return: Success(0) or reason code for failure
1715 */
1716static int32_t
1717hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1718 struct wireless_dev *wdev,
1719 const void *data,
1720 int data_len)
1721{
1722 int ret;
1723
1724 vos_ssr_protect(__func__);
1725 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1726 vos_ssr_unprotect(__func__);
1727
1728 return ret;
1729}
1730
1731/*
1732 * undef short names defined for get station command
1733 * used by __wlan_hdd_cfg80211_get_station_cmd()
1734 */
1735#undef STATION_INVALID
1736#undef STATION_INFO
1737#undef STATION_ASSOC_FAIL_REASON
1738#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301739
Sunil Duttc69bccb2014-05-26 21:30:20 +05301740#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1741
1742static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1743 struct sk_buff *vendor_event)
1744{
1745 if (nla_put_u8(vendor_event,
1746 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1747 stats->rate.preamble) ||
1748 nla_put_u8(vendor_event,
1749 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1750 stats->rate.nss) ||
1751 nla_put_u8(vendor_event,
1752 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1753 stats->rate.bw) ||
1754 nla_put_u8(vendor_event,
1755 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1756 stats->rate.rateMcsIdx) ||
1757 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1758 stats->rate.bitrate ) ||
1759 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1760 stats->txMpdu ) ||
1761 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1762 stats->rxMpdu ) ||
1763 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1764 stats->mpduLost ) ||
1765 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1766 stats->retries) ||
1767 nla_put_u32(vendor_event,
1768 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1769 stats->retriesShort ) ||
1770 nla_put_u32(vendor_event,
1771 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1772 stats->retriesLong))
1773 {
1774 hddLog(VOS_TRACE_LEVEL_ERROR,
1775 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1776 return FALSE;
1777 }
1778 return TRUE;
1779}
1780
1781static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1782 struct sk_buff *vendor_event)
1783{
1784 u32 i = 0;
1785 struct nlattr *rateInfo;
1786 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1787 stats->type) ||
1788 nla_put(vendor_event,
1789 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1790 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1791 nla_put_u32(vendor_event,
1792 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1793 stats->capabilities) ||
1794 nla_put_u32(vendor_event,
1795 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1796 stats->numRate))
1797 {
1798 hddLog(VOS_TRACE_LEVEL_ERROR,
1799 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1800 goto error;
1801 }
1802
1803 rateInfo = nla_nest_start(vendor_event,
1804 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301805 if(!rateInfo)
1806 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 for (i = 0; i < stats->numRate; i++)
1808 {
1809 struct nlattr *rates;
1810 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1811 stats->rateStats +
1812 (i * sizeof(tSirWifiRateStat)));
1813 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301814 if(!rates)
1815 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301816
1817 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1818 {
1819 hddLog(VOS_TRACE_LEVEL_ERROR,
1820 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1821 return FALSE;
1822 }
1823 nla_nest_end(vendor_event, rates);
1824 }
1825 nla_nest_end(vendor_event, rateInfo);
1826
1827 return TRUE;
1828error:
1829 return FALSE;
1830}
1831
1832static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1833 struct sk_buff *vendor_event)
1834{
1835 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1836 stats->ac ) ||
1837 nla_put_u32(vendor_event,
1838 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1839 stats->txMpdu ) ||
1840 nla_put_u32(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1842 stats->rxMpdu ) ||
1843 nla_put_u32(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1845 stats->txMcast ) ||
1846 nla_put_u32(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1848 stats->rxMcast ) ||
1849 nla_put_u32(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1851 stats->rxAmpdu ) ||
1852 nla_put_u32(vendor_event,
1853 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1854 stats->txAmpdu ) ||
1855 nla_put_u32(vendor_event,
1856 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1857 stats->mpduLost )||
1858 nla_put_u32(vendor_event,
1859 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1860 stats->retries ) ||
1861 nla_put_u32(vendor_event,
1862 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1863 stats->retriesShort ) ||
1864 nla_put_u32(vendor_event,
1865 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1866 stats->retriesLong ) ||
1867 nla_put_u32(vendor_event,
1868 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1869 stats->contentionTimeMin ) ||
1870 nla_put_u32(vendor_event,
1871 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1872 stats->contentionTimeMax ) ||
1873 nla_put_u32(vendor_event,
1874 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1875 stats->contentionTimeAvg ) ||
1876 nla_put_u32(vendor_event,
1877 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1878 stats->contentionNumSamples ))
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR,
1881 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1882 return FALSE;
1883 }
1884 return TRUE;
1885}
1886
1887static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1888 struct sk_buff *vendor_event)
1889{
Dino Myclec8f3f332014-07-21 16:48:27 +05301890 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1892 nla_put(vendor_event,
1893 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1894 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1895 nla_put_u32(vendor_event,
1896 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1897 stats->state ) ||
1898 nla_put_u32(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1900 stats->roaming ) ||
1901 nla_put_u32(vendor_event,
1902 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1903 stats->capabilities ) ||
1904 nla_put(vendor_event,
1905 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1906 strlen(stats->ssid), stats->ssid) ||
1907 nla_put(vendor_event,
1908 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1909 WNI_CFG_BSSID_LEN, stats->bssid) ||
1910 nla_put(vendor_event,
1911 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1912 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1913 nla_put(vendor_event,
1914 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1915 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1916 )
1917 {
1918 hddLog(VOS_TRACE_LEVEL_ERROR,
1919 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1920 return FALSE;
1921 }
1922 return TRUE;
1923}
1924
Dino Mycle3b9536d2014-07-09 22:05:24 +05301925static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1926 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 struct sk_buff *vendor_event)
1928{
1929 int i = 0;
1930 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301931 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1932 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301933 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301934
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 if (FALSE == put_wifi_interface_info(
1936 &pWifiIfaceStat->info,
1937 vendor_event))
1938 {
1939 hddLog(VOS_TRACE_LEVEL_ERROR,
1940 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1941 return FALSE;
1942
1943 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301944 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1945 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1946 if (NULL == pWifiIfaceStatTL)
1947 {
1948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1949 return FALSE;
1950 }
1951
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301952 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1953 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1954 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1955 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1956
1957 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1958 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1959 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1960 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301961
1962 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1963 {
1964 if (VOS_STATUS_SUCCESS ==
1965 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1966 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1967 {
1968 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1969 * obtained from TL structure
1970 */
1971
1972 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1973 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301974 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1975
Srinivas Dasari98947432014-11-07 19:41:24 +05301976 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1977 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1978 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1979 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1980 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1981 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1982 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1983 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301984
Srinivas Dasari98947432014-11-07 19:41:24 +05301985 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1986 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1987 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1988 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1989 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1990 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1991 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1992 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301993
Srinivas Dasari98947432014-11-07 19:41:24 +05301994 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1995 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1996 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1997 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1998 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1999 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2000 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2001 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302002 }
2003 else
2004 {
2005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2006 }
2007
Dino Mycle3b9536d2014-07-09 22:05:24 +05302008 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2009 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2010 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2011 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2013 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2015 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2016 }
2017 else
2018 {
2019 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2020 }
2021
2022
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023
2024 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302025 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2027 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302028 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2029 pWifiIfaceStat->beaconRx) ||
2030 nla_put_u32(vendor_event,
2031 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2032 pWifiIfaceStat->mgmtRx) ||
2033 nla_put_u32(vendor_event,
2034 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2035 pWifiIfaceStat->mgmtActionRx) ||
2036 nla_put_u32(vendor_event,
2037 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2038 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302040 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2041 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302042 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2044 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302045 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302046 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2047 pWifiIfaceStat->rssiAck))
2048 {
2049 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302050 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2051 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302052 return FALSE;
2053 }
2054
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302055#ifdef FEATURE_EXT_LL_STAT
2056 /*
2057 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2058 * then host should send Leaky AP stats to upper layer,
2059 * otherwise no need to send these stats.
2060 */
2061 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2062 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2063 )
2064 {
2065 hddLog(VOS_TRACE_LEVEL_INFO,
2066 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2067 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2068 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2069 pWifiIfaceStat->leakyApStat.rx_leak_window,
2070 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2071 if (nla_put_u32(vendor_event,
2072 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2073 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2074 nla_put_u32(vendor_event,
2075 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2076 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2077 nla_put_u32(vendor_event,
2078 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2079 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302080 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302081 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2082 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2083 {
2084 hddLog(VOS_TRACE_LEVEL_ERROR,
2085 FL("EXT_LL_STAT put fail"));
2086 vos_mem_free(pWifiIfaceStatTL);
2087 return FALSE;
2088 }
2089 }
2090#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 wmmInfo = nla_nest_start(vendor_event,
2092 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302093 if(!wmmInfo)
2094 {
2095 vos_mem_free(pWifiIfaceStatTL);
2096 return FALSE;
2097 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302098 for (i = 0; i < WIFI_AC_MAX; i++)
2099 {
2100 struct nlattr *wmmStats;
2101 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302102 if(!wmmStats)
2103 {
2104 vos_mem_free(pWifiIfaceStatTL);
2105 return FALSE;
2106 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302107 if (FALSE == put_wifi_wmm_ac_stat(
2108 &pWifiIfaceStat->AccessclassStats[i],
2109 vendor_event))
2110 {
2111 hddLog(VOS_TRACE_LEVEL_ERROR,
2112 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302113 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 return FALSE;
2115 }
2116
2117 nla_nest_end(vendor_event, wmmStats);
2118 }
2119 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302120 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302121 return TRUE;
2122}
2123
2124static tSirWifiInterfaceMode
2125 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2126{
2127 switch (deviceMode)
2128 {
2129 case WLAN_HDD_INFRA_STATION:
2130 return WIFI_INTERFACE_STA;
2131 case WLAN_HDD_SOFTAP:
2132 return WIFI_INTERFACE_SOFTAP;
2133 case WLAN_HDD_P2P_CLIENT:
2134 return WIFI_INTERFACE_P2P_CLIENT;
2135 case WLAN_HDD_P2P_GO:
2136 return WIFI_INTERFACE_P2P_GO;
2137 case WLAN_HDD_IBSS:
2138 return WIFI_INTERFACE_IBSS;
2139 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302140 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 }
2142}
2143
2144static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2145 tpSirWifiInterfaceInfo pInfo)
2146{
2147 v_U8_t *staMac = NULL;
2148 hdd_station_ctx_t *pHddStaCtx;
2149 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2150 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2151
2152 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2153
2154 vos_mem_copy(pInfo->macAddr,
2155 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2156
2157 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2158 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2159 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2160 {
2161 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2162 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2163 {
2164 pInfo->state = WIFI_DISCONNECTED;
2165 }
2166 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2167 {
2168 hddLog(VOS_TRACE_LEVEL_ERROR,
2169 "%s: Session ID %d, Connection is in progress", __func__,
2170 pAdapter->sessionId);
2171 pInfo->state = WIFI_ASSOCIATING;
2172 }
2173 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2174 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2175 {
2176 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2177 hddLog(VOS_TRACE_LEVEL_ERROR,
2178 "%s: client " MAC_ADDRESS_STR
2179 " is in the middle of WPS/EAPOL exchange.", __func__,
2180 MAC_ADDR_ARRAY(staMac));
2181 pInfo->state = WIFI_AUTHENTICATING;
2182 }
2183 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2184 {
2185 pInfo->state = WIFI_ASSOCIATED;
2186 vos_mem_copy(pInfo->bssid,
2187 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2188 vos_mem_copy(pInfo->ssid,
2189 pHddStaCtx->conn_info.SSID.SSID.ssId,
2190 pHddStaCtx->conn_info.SSID.SSID.length);
2191 //NULL Terminate the string.
2192 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2193 }
2194 }
2195 vos_mem_copy(pInfo->countryStr,
2196 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2197
2198 vos_mem_copy(pInfo->apCountryStr,
2199 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2200
2201 return TRUE;
2202}
2203
2204/*
2205 * hdd_link_layer_process_peer_stats () - This function is called after
2206 * receiving Link Layer Peer statistics from FW.This function converts
2207 * the firmware data to the NL data and sends the same to the kernel/upper
2208 * layers.
2209 */
2210static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2211 v_VOID_t *pData)
2212{
2213 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 tpSirWifiPeerStat pWifiPeerStat;
2215 tpSirWifiPeerInfo pWifiPeerInfo;
2216 struct nlattr *peerInfo;
2217 struct sk_buff *vendor_event;
2218 int status, i;
2219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302220 ENTER();
2221
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222 status = wlan_hdd_validate_context(pHddCtx);
2223 if (0 != status)
2224 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 return;
2226 }
2227
2228 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2229
2230 hddLog(VOS_TRACE_LEVEL_INFO,
2231 "LL_STATS_PEER_ALL : numPeers %u",
2232 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302233 /*
2234 * Allocate a size of 4096 for the peer stats comprising
2235 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2236 * sizeof (tSirWifiRateStat).Each field is put with an
2237 * NL attribute.The size of 4096 is considered assuming
2238 * that number of rates shall not exceed beyond 50 with
2239 * the sizeof (tSirWifiRateStat) being 32.
2240 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302241 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2242 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302243 if (!vendor_event)
2244 {
2245 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302246 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302247 __func__);
2248 return;
2249 }
2250 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302251 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2252 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2253 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302254 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2255 pWifiPeerStat->numPeers))
2256 {
2257 hddLog(VOS_TRACE_LEVEL_ERROR,
2258 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2259 kfree_skb(vendor_event);
2260 return;
2261 }
2262
2263 peerInfo = nla_nest_start(vendor_event,
2264 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302265 if(!peerInfo)
2266 {
2267 hddLog(VOS_TRACE_LEVEL_ERROR,
2268 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2269 __func__);
2270 kfree_skb(vendor_event);
2271 return;
2272 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302273
2274 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2275 pWifiPeerStat->peerInfo);
2276
2277 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2278 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302279 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302280 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302281
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302282 if(!peers)
2283 {
2284 hddLog(VOS_TRACE_LEVEL_ERROR,
2285 "%s: peer stats put fail",
2286 __func__);
2287 kfree_skb(vendor_event);
2288 return;
2289 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302290 if (FALSE == put_wifi_peer_info(
2291 pWifiPeerInfo, vendor_event))
2292 {
2293 hddLog(VOS_TRACE_LEVEL_ERROR,
2294 "%s: put_wifi_peer_info put fail", __func__);
2295 kfree_skb(vendor_event);
2296 return;
2297 }
2298
2299 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2300 pWifiPeerStat->peerInfo +
2301 (i * sizeof(tSirWifiPeerInfo)) +
2302 (numRate * sizeof (tSirWifiRateStat)));
2303 nla_nest_end(vendor_event, peers);
2304 }
2305 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302306 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302307 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302308}
2309
2310/*
2311 * hdd_link_layer_process_iface_stats () - This function is called after
2312 * receiving Link Layer Interface statistics from FW.This function converts
2313 * the firmware data to the NL data and sends the same to the kernel/upper
2314 * layers.
2315 */
2316static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2317 v_VOID_t *pData)
2318{
2319 tpSirWifiIfaceStat pWifiIfaceStat;
2320 struct sk_buff *vendor_event;
2321 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2322 int status;
2323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302324 ENTER();
2325
Sunil Duttc69bccb2014-05-26 21:30:20 +05302326 status = wlan_hdd_validate_context(pHddCtx);
2327 if (0 != status)
2328 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 return;
2330 }
2331 /*
2332 * Allocate a size of 4096 for the interface stats comprising
2333 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2334 * assuming that all these fit with in the limit.Please take
2335 * a call on the limit based on the data requirements on
2336 * interface statistics.
2337 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302338 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2339 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302340 if (!vendor_event)
2341 {
2342 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302343 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302344 return;
2345 }
2346
2347 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2348
Dino Mycle3b9536d2014-07-09 22:05:24 +05302349
2350 if (FALSE == hdd_get_interface_info( pAdapter,
2351 &pWifiIfaceStat->info))
2352 {
2353 hddLog(VOS_TRACE_LEVEL_ERROR,
2354 FL("hdd_get_interface_info get fail") );
2355 kfree_skb(vendor_event);
2356 return;
2357 }
2358
2359 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2360 vendor_event))
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 FL("put_wifi_iface_stats fail") );
2364 kfree_skb(vendor_event);
2365 return;
2366 }
2367
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368 hddLog(VOS_TRACE_LEVEL_INFO,
2369 "WMI_LINK_STATS_IFACE Data");
2370
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302371 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302372
2373 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302374}
2375
2376/*
2377 * hdd_link_layer_process_radio_stats () - This function is called after
2378 * receiving Link Layer Radio statistics from FW.This function converts
2379 * the firmware data to the NL data and sends the same to the kernel/upper
2380 * layers.
2381 */
2382static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2383 v_VOID_t *pData)
2384{
2385 int status, i;
2386 tpSirWifiRadioStat pWifiRadioStat;
2387 tpSirWifiChannelStats pWifiChannelStats;
2388 struct sk_buff *vendor_event;
2389 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2390 struct nlattr *chList;
2391
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302392 ENTER();
2393
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394 status = wlan_hdd_validate_context(pHddCtx);
2395 if (0 != status)
2396 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302397 return;
2398 }
2399 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2400
2401 hddLog(VOS_TRACE_LEVEL_INFO,
2402 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302403 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302404 " radio is %d onTime is %u "
2405 " txTime is %u rxTime is %u "
2406 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302407 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302408 " onTimePnoScan is %u onTimeHs20 is %u "
2409 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302410 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302411 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2412 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2413 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302414 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302415 pWifiRadioStat->onTimeRoamScan,
2416 pWifiRadioStat->onTimePnoScan,
2417 pWifiRadioStat->onTimeHs20,
2418 pWifiRadioStat->numChannels);
2419 /*
2420 * Allocate a size of 4096 for the Radio stats comprising
2421 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2422 * (tSirWifiChannelStats).Each channel data is put with an
2423 * NL attribute.The size of 4096 is considered assuming that
2424 * number of channels shall not exceed beyond 60 with the
2425 * sizeof (tSirWifiChannelStats) being 24 bytes.
2426 */
2427
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302428 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2429 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302430 if (!vendor_event)
2431 {
2432 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302434 return;
2435 }
2436
2437 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302438 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2439 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2440 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302441 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2442 pWifiRadioStat->radio) ||
2443 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302444 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2445 NUM_RADIOS) ||
2446 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302447 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2448 pWifiRadioStat->onTime) ||
2449 nla_put_u32(vendor_event,
2450 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2451 pWifiRadioStat->txTime) ||
2452 nla_put_u32(vendor_event,
2453 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2454 pWifiRadioStat->rxTime) ||
2455 nla_put_u32(vendor_event,
2456 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2457 pWifiRadioStat->onTimeScan) ||
2458 nla_put_u32(vendor_event,
2459 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2460 pWifiRadioStat->onTimeNbd) ||
2461 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2463 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302464 nla_put_u32(vendor_event,
2465 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2466 pWifiRadioStat->onTimeRoamScan) ||
2467 nla_put_u32(vendor_event,
2468 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2469 pWifiRadioStat->onTimePnoScan) ||
2470 nla_put_u32(vendor_event,
2471 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2472 pWifiRadioStat->onTimeHs20) ||
2473 nla_put_u32(vendor_event,
2474 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2475 pWifiRadioStat->numChannels))
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR,
2478 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2479 kfree_skb(vendor_event);
2480 return ;
2481 }
2482
2483 chList = nla_nest_start(vendor_event,
2484 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302485 if(!chList)
2486 {
2487 hddLog(VOS_TRACE_LEVEL_ERROR,
2488 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2489 __func__);
2490 kfree_skb(vendor_event);
2491 return;
2492 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302493 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2494 {
2495 struct nlattr *chInfo;
2496
2497 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2498 pWifiRadioStat->channels +
2499 (i * sizeof(tSirWifiChannelStats)));
2500
Sunil Duttc69bccb2014-05-26 21:30:20 +05302501 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302502 if(!chInfo)
2503 {
2504 hddLog(VOS_TRACE_LEVEL_ERROR,
2505 "%s: failed to put chInfo",
2506 __func__);
2507 kfree_skb(vendor_event);
2508 return;
2509 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510
2511 if (nla_put_u32(vendor_event,
2512 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2513 pWifiChannelStats->channel.width) ||
2514 nla_put_u32(vendor_event,
2515 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2516 pWifiChannelStats->channel.centerFreq) ||
2517 nla_put_u32(vendor_event,
2518 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2519 pWifiChannelStats->channel.centerFreq0) ||
2520 nla_put_u32(vendor_event,
2521 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2522 pWifiChannelStats->channel.centerFreq1) ||
2523 nla_put_u32(vendor_event,
2524 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2525 pWifiChannelStats->onTime) ||
2526 nla_put_u32(vendor_event,
2527 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2528 pWifiChannelStats->ccaBusyTime))
2529 {
2530 hddLog(VOS_TRACE_LEVEL_ERROR,
2531 FL("cfg80211_vendor_event_alloc failed") );
2532 kfree_skb(vendor_event);
2533 return ;
2534 }
2535 nla_nest_end(vendor_event, chInfo);
2536 }
2537 nla_nest_end(vendor_event, chList);
2538
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302539 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302540
2541 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302542 return;
2543}
2544
2545/*
2546 * hdd_link_layer_stats_ind_callback () - This function is called after
2547 * receiving Link Layer indications from FW.This callback converts the firmware
2548 * data to the NL data and send the same to the kernel/upper layers.
2549 */
2550static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2551 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302552 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302553{
Dino Mycled3d50022014-07-07 12:58:25 +05302554 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2555 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302556 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302557 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302558 int status;
2559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302560 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302561
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302562 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302563 if (0 != status)
2564 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302565 return;
2566 }
2567
Dino Mycled3d50022014-07-07 12:58:25 +05302568 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2569 if (NULL == pAdapter)
2570 {
2571 hddLog(VOS_TRACE_LEVEL_ERROR,
2572 FL(" MAC address %pM does not exist with host"),
2573 macAddr);
2574 return;
2575 }
2576
Sunil Duttc69bccb2014-05-26 21:30:20 +05302577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302578 "%s: Interface: %s LLStats indType: %d", __func__,
2579 pAdapter->dev->name, indType);
2580
Sunil Duttc69bccb2014-05-26 21:30:20 +05302581 switch (indType)
2582 {
2583 case SIR_HAL_LL_STATS_RESULTS_RSP:
2584 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302585 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302586 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2587 "respId = %u, moreResultToFollow = %u",
2588 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2589 macAddr, linkLayerStatsResults->respId,
2590 linkLayerStatsResults->moreResultToFollow);
2591
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302592 spin_lock(&hdd_context_lock);
2593 context = &pHddCtx->ll_stats_context;
2594 /* validate response received from target */
2595 if ((context->request_id != linkLayerStatsResults->respId) ||
2596 !(context->request_bitmap & linkLayerStatsResults->paramId))
2597 {
2598 spin_unlock(&hdd_context_lock);
2599 hddLog(LOGE,
2600 FL("Error : Request id %d response id %d request bitmap 0x%x"
2601 "response bitmap 0x%x"),
2602 context->request_id, linkLayerStatsResults->respId,
2603 context->request_bitmap, linkLayerStatsResults->paramId);
2604 return;
2605 }
2606 spin_unlock(&hdd_context_lock);
2607
Sunil Duttc69bccb2014-05-26 21:30:20 +05302608 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2609 {
2610 hdd_link_layer_process_radio_stats(pAdapter,
2611 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302612 spin_lock(&hdd_context_lock);
2613 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2614 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302615 }
2616 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2617 {
2618 hdd_link_layer_process_iface_stats(pAdapter,
2619 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302620 spin_lock(&hdd_context_lock);
2621 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2622 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302623 }
2624 else if ( linkLayerStatsResults->paramId &
2625 WMI_LINK_STATS_ALL_PEER )
2626 {
2627 hdd_link_layer_process_peer_stats(pAdapter,
2628 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302629 spin_lock(&hdd_context_lock);
2630 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2631 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302632 } /* WMI_LINK_STATS_ALL_PEER */
2633 else
2634 {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2637 }
2638
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302639 spin_lock(&hdd_context_lock);
2640 /* complete response event if all requests are completed */
2641 if (0 == context->request_bitmap)
2642 complete(&context->response_event);
2643 spin_unlock(&hdd_context_lock);
2644
Sunil Duttc69bccb2014-05-26 21:30:20 +05302645 break;
2646 }
2647 default:
2648 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2649 break;
2650 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302651
2652 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302653 return;
2654}
2655
2656const struct
2657nla_policy
2658qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2659{
2660 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2661 { .type = NLA_U32 },
2662 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2663 { .type = NLA_U32 },
2664};
2665
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302666static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2667 struct wireless_dev *wdev,
2668 const void *data,
2669 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302670{
2671 int status;
2672 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302673 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302674 struct net_device *dev = wdev->netdev;
2675 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2676 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2677
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302678 ENTER();
2679
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 status = wlan_hdd_validate_context(pHddCtx);
2681 if (0 != status)
2682 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302683 return -EINVAL;
2684 }
2685
2686 if (NULL == pAdapter)
2687 {
2688 hddLog(VOS_TRACE_LEVEL_ERROR,
2689 FL("HDD adapter is Null"));
2690 return -ENODEV;
2691 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302692 /* check the LLStats Capability */
2693 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2694 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2695 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302696 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302697 FL("Link Layer Statistics not supported by Firmware"));
2698 return -EINVAL;
2699 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302700
2701 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2702 (struct nlattr *)data,
2703 data_len, qca_wlan_vendor_ll_set_policy))
2704 {
2705 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2706 return -EINVAL;
2707 }
2708 if (!tb_vendor
2709 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2710 {
2711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2712 return -EINVAL;
2713 }
2714 if (!tb_vendor[
2715 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2716 {
2717 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2718 return -EINVAL;
2719 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302720 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302721 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302722
Dino Mycledf0a5d92014-07-04 09:41:55 +05302723 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302724 nla_get_u32(
2725 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2726
Dino Mycledf0a5d92014-07-04 09:41:55 +05302727 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302728 nla_get_u32(
2729 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2730
Dino Mycled3d50022014-07-07 12:58:25 +05302731 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2732 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302733
2734
2735 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302736 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2737 "Statistics Gathering = %d ",
2738 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2739 linkLayerStatsSetReq.mpduSizeThreshold,
2740 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302741
2742 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2743 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302744 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2747 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 return -EINVAL;
2749
2750 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302751
Sunil Duttc69bccb2014-05-26 21:30:20 +05302752 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302753 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302754 {
2755 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2756 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302757 return -EINVAL;
2758 }
2759
2760 pAdapter->isLinkLayerStatsSet = 1;
2761
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302762 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302763 return 0;
2764}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302765static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2766 struct wireless_dev *wdev,
2767 const void *data,
2768 int data_len)
2769{
2770 int ret = 0;
2771
2772 vos_ssr_protect(__func__);
2773 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2774 vos_ssr_unprotect(__func__);
2775
2776 return ret;
2777}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778
2779const struct
2780nla_policy
2781qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2782{
2783 /* Unsigned 32bit value provided by the caller issuing the GET stats
2784 * command. When reporting
2785 * the stats results, the driver uses the same value to indicate
2786 * which GET request the results
2787 * correspond to.
2788 */
2789 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2790
2791 /* Unsigned 32bit value . bit mask to identify what statistics are
2792 requested for retrieval */
2793 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2794};
2795
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302796static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2797 struct wireless_dev *wdev,
2798 const void *data,
2799 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302800{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302801 unsigned long rc;
2802 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302803 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2804 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302805 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302806 struct net_device *dev = wdev->netdev;
2807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302808 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302809 int status;
2810
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302811 ENTER();
2812
Sunil Duttc69bccb2014-05-26 21:30:20 +05302813 status = wlan_hdd_validate_context(pHddCtx);
2814 if (0 != status)
2815 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302816 return -EINVAL ;
2817 }
2818
2819 if (NULL == pAdapter)
2820 {
2821 hddLog(VOS_TRACE_LEVEL_FATAL,
2822 "%s: HDD adapter is Null", __func__);
2823 return -ENODEV;
2824 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302825
2826 if (pHddStaCtx == NULL)
2827 {
2828 hddLog(VOS_TRACE_LEVEL_FATAL,
2829 "%s: HddStaCtx is Null", __func__);
2830 return -ENODEV;
2831 }
2832
Dino Mycledf0a5d92014-07-04 09:41:55 +05302833 /* check the LLStats Capability */
2834 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2835 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2836 {
2837 hddLog(VOS_TRACE_LEVEL_ERROR,
2838 FL("Link Layer Statistics not supported by Firmware"));
2839 return -EINVAL;
2840 }
2841
Sunil Duttc69bccb2014-05-26 21:30:20 +05302842
2843 if (!pAdapter->isLinkLayerStatsSet)
2844 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302845 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302846 "%s: isLinkLayerStatsSet : %d",
2847 __func__, pAdapter->isLinkLayerStatsSet);
2848 return -EINVAL;
2849 }
2850
Mukul Sharma10313ba2015-07-29 19:14:39 +05302851 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2852 {
2853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2854 "%s: Roaming in progress, so unable to proceed this request", __func__);
2855 return -EBUSY;
2856 }
2857
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2859 (struct nlattr *)data,
2860 data_len, qca_wlan_vendor_ll_get_policy))
2861 {
2862 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2863 return -EINVAL;
2864 }
2865
2866 if (!tb_vendor
2867 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2868 {
2869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2870 return -EINVAL;
2871 }
2872
2873 if (!tb_vendor
2874 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2875 {
2876 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2877 return -EINVAL;
2878 }
2879
Sunil Duttc69bccb2014-05-26 21:30:20 +05302880
Dino Mycledf0a5d92014-07-04 09:41:55 +05302881 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302882 nla_get_u32( tb_vendor[
2883 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302884 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302885 nla_get_u32( tb_vendor[
2886 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2887
Dino Mycled3d50022014-07-07 12:58:25 +05302888 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2889 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302890
2891 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302892 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2893 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302894 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302896 spin_lock(&hdd_context_lock);
2897 context = &pHddCtx->ll_stats_context;
2898 context->request_id = linkLayerStatsGetReq.reqId;
2899 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2900 INIT_COMPLETION(context->response_event);
2901 spin_unlock(&hdd_context_lock);
2902
Sunil Duttc69bccb2014-05-26 21:30:20 +05302903 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302904 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302905 {
2906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2907 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 return -EINVAL;
2909 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302910
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302911 rc = wait_for_completion_timeout(&context->response_event,
2912 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2913 if (!rc)
2914 {
2915 hddLog(LOGE,
2916 FL("Target response timed out request id %d request bitmap 0x%x"),
2917 context->request_id, context->request_bitmap);
2918 return -ETIMEDOUT;
2919 }
2920
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302921 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302922 return 0;
2923}
2924
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302925static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2926 struct wireless_dev *wdev,
2927 const void *data,
2928 int data_len)
2929{
2930 int ret = 0;
2931
2932 vos_ssr_protect(__func__);
2933 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2934 vos_ssr_unprotect(__func__);
2935
2936 return ret;
2937}
2938
Sunil Duttc69bccb2014-05-26 21:30:20 +05302939const struct
2940nla_policy
2941qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2942{
2943 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2944 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2945 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2946 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2947};
2948
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302949static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2950 struct wireless_dev *wdev,
2951 const void *data,
2952 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953{
2954 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2955 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302956 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302957 struct net_device *dev = wdev->netdev;
2958 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2959 u32 statsClearReqMask;
2960 u8 stopReq;
2961 int status;
2962
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302963 ENTER();
2964
Sunil Duttc69bccb2014-05-26 21:30:20 +05302965 status = wlan_hdd_validate_context(pHddCtx);
2966 if (0 != status)
2967 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302968 return -EINVAL;
2969 }
2970
2971 if (NULL == pAdapter)
2972 {
2973 hddLog(VOS_TRACE_LEVEL_FATAL,
2974 "%s: HDD adapter is Null", __func__);
2975 return -ENODEV;
2976 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302977 /* check the LLStats Capability */
2978 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2979 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2980 {
2981 hddLog(VOS_TRACE_LEVEL_ERROR,
2982 FL("Enable LLStats Capability"));
2983 return -EINVAL;
2984 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
2986 if (!pAdapter->isLinkLayerStatsSet)
2987 {
2988 hddLog(VOS_TRACE_LEVEL_FATAL,
2989 "%s: isLinkLayerStatsSet : %d",
2990 __func__, pAdapter->isLinkLayerStatsSet);
2991 return -EINVAL;
2992 }
2993
2994 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2995 (struct nlattr *)data,
2996 data_len, qca_wlan_vendor_ll_clr_policy))
2997 {
2998 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2999 return -EINVAL;
3000 }
3001
3002 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3003
3004 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3005 {
3006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3007 return -EINVAL;
3008
3009 }
3010
Sunil Duttc69bccb2014-05-26 21:30:20 +05303011
Dino Mycledf0a5d92014-07-04 09:41:55 +05303012 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303013 nla_get_u32(
3014 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3015
Dino Mycledf0a5d92014-07-04 09:41:55 +05303016 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017 nla_get_u8(
3018 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3019
3020 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303021 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303022
Dino Mycled3d50022014-07-07 12:58:25 +05303023 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3024 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303025
3026 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303027 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3028 "statsClearReqMask = 0x%X, stopReq = %d",
3029 linkLayerStatsClearReq.reqId,
3030 linkLayerStatsClearReq.macAddr,
3031 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303032 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303033
3034 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303035 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303036 {
3037 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303038 hdd_station_ctx_t *pHddStaCtx;
3039
3040 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3041 if (VOS_STATUS_SUCCESS !=
3042 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3043 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3044 {
3045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3046 "WLANTL_ClearInterfaceStats Failed", __func__);
3047 return -EINVAL;
3048 }
3049 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3050 (statsClearReqMask & WIFI_STATS_IFACE)) {
3051 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3052 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3053 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3054 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3055 }
3056
Sunil Duttc69bccb2014-05-26 21:30:20 +05303057 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3058 2 * sizeof(u32) +
3059 NLMSG_HDRLEN);
3060
3061 if (temp_skbuff != NULL)
3062 {
3063
3064 if (nla_put_u32(temp_skbuff,
3065 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3066 statsClearReqMask) ||
3067 nla_put_u32(temp_skbuff,
3068 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3069 stopReq))
3070 {
3071 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3072 kfree_skb(temp_skbuff);
3073 return -EINVAL;
3074 }
3075 /* If the ask is to stop the stats collection as part of clear
3076 * (stopReq = 1) , ensure that no further requests of get
3077 * go to the firmware by having isLinkLayerStatsSet set to 0.
3078 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303079 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080 * case the firmware is just asked to clear the statistics.
3081 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303082 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303083 pAdapter->isLinkLayerStatsSet = 0;
3084 return cfg80211_vendor_cmd_reply(temp_skbuff);
3085 }
3086 return -ENOMEM;
3087 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303088
3089 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303090 return -EINVAL;
3091}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303092static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3093 struct wireless_dev *wdev,
3094 const void *data,
3095 int data_len)
3096{
3097 int ret = 0;
3098
3099 vos_ssr_protect(__func__);
3100 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3101 vos_ssr_unprotect(__func__);
3102
3103 return ret;
3104
3105
3106}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303107#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3108
Dino Mycle6fb96c12014-06-10 11:52:40 +05303109#ifdef WLAN_FEATURE_EXTSCAN
3110static const struct nla_policy
3111wlan_hdd_extscan_config_policy
3112 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3113{
3114 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3115 { .type = NLA_U32 },
3116 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3117 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3119 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303120 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3122 { .type = NLA_U32 },
3123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3125
3126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3130 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303131 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3132 { .type = NLA_U32 },
3133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3134 { .type = NLA_U32 },
3135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3136 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3138 { .type = NLA_U32 },
3139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3140 { .type = NLA_U32 },
3141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3142 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3144 { .type = NLA_U8 },
3145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303146 { .type = NLA_U8 },
3147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3148 { .type = NLA_U8 },
3149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3150 { .type = NLA_U8 },
3151
3152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3153 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3155 .type = NLA_UNSPEC,
3156 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3158 { .type = NLA_S32 },
3159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3160 { .type = NLA_S32 },
3161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3162 { .type = NLA_U32 },
3163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3164 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3166 { .type = NLA_U32 },
3167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3168 { .type = NLA_BINARY,
3169 .len = IEEE80211_MAX_SSID_LEN + 1 },
3170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3173 { .type = NLA_U32 },
3174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3175 { .type = NLA_U8 },
3176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3177 { .type = NLA_S32 },
3178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3179 { .type = NLA_S32 },
3180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3181 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182};
3183
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303184/**
3185 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3186 * @ctx: hdd global context
3187 * @data: capabilities data
3188 *
3189 * Return: none
3190 */
3191static void
3192wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303194 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303196 tSirEXTScanCapabilitiesEvent *data =
3197 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303198
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303199 ENTER();
3200
3201 if (wlan_hdd_validate_context(pHddCtx))
3202 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303203 return;
3204 }
3205
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303206 if (!pMsg)
3207 {
3208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3209 return;
3210 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303212 vos_spin_lock_acquire(&hdd_context_lock);
3213
3214 context = &pHddCtx->ext_scan_context;
3215 /* validate response received from target*/
3216 if (context->request_id != data->requestId)
3217 {
3218 vos_spin_lock_release(&hdd_context_lock);
3219 hddLog(LOGE,
3220 FL("Target response id did not match: request_id %d resposne_id %d"),
3221 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 return;
3223 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303224 else
3225 {
3226 context->capability_response = *data;
3227 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303228 }
3229
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303230 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303231
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 return;
3233}
3234
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303235/*
3236 * define short names for the global vendor params
3237 * used by wlan_hdd_send_ext_scan_capability()
3238 */
3239#define PARAM_REQUEST_ID \
3240 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3241#define PARAM_STATUS \
3242 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3243#define MAX_SCAN_CACHE_SIZE \
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3245#define MAX_SCAN_BUCKETS \
3246 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3247#define MAX_AP_CACHE_PER_SCAN \
3248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3249#define MAX_RSSI_SAMPLE_SIZE \
3250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3251#define MAX_SCAN_RPT_THRHOLD \
3252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3253#define MAX_HOTLIST_BSSIDS \
3254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3255#define MAX_BSSID_HISTORY_ENTRIES \
3256 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3257#define MAX_HOTLIST_SSIDS \
3258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303259#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303261
3262static int wlan_hdd_send_ext_scan_capability(void *ctx)
3263{
3264 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3265 struct sk_buff *skb = NULL;
3266 int ret;
3267 tSirEXTScanCapabilitiesEvent *data;
3268 tANI_U32 nl_buf_len;
3269
3270 ret = wlan_hdd_validate_context(pHddCtx);
3271 if (0 != ret)
3272 {
3273 return ret;
3274 }
3275
3276 data = &(pHddCtx->ext_scan_context.capability_response);
3277
3278 nl_buf_len = NLMSG_HDRLEN;
3279 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3280 (sizeof(data->status) + NLA_HDRLEN) +
3281 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3282 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3283 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3284 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3285 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3286 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3287 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3288 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3289
3290 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3291
3292 if (!skb)
3293 {
3294 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3295 return -ENOMEM;
3296 }
3297
3298 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3299 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3300 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3301 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3302 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3303 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3304 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3305 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3306
3307 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3308 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3309 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3310 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3311 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3312 data->maxApPerScan) ||
3313 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3314 data->maxRssiSampleSize) ||
3315 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3316 data->maxScanReportingThreshold) ||
3317 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3318 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3319 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303320 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3321 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303322 {
3323 hddLog(LOGE, FL("nla put fail"));
3324 goto nla_put_failure;
3325 }
3326
3327 cfg80211_vendor_cmd_reply(skb);
3328 return 0;
3329
3330nla_put_failure:
3331 kfree_skb(skb);
3332 return -EINVAL;;
3333}
3334
3335/*
3336 * done with short names for the global vendor params
3337 * used by wlan_hdd_send_ext_scan_capability()
3338 */
3339#undef PARAM_REQUEST_ID
3340#undef PARAM_STATUS
3341#undef MAX_SCAN_CACHE_SIZE
3342#undef MAX_SCAN_BUCKETS
3343#undef MAX_AP_CACHE_PER_SCAN
3344#undef MAX_RSSI_SAMPLE_SIZE
3345#undef MAX_SCAN_RPT_THRHOLD
3346#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303347#undef MAX_BSSID_HISTORY_ENTRIES
3348#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349
3350static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3351{
3352 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3353 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303355 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303357 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303358
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303359 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303360 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303362 if (!pMsg)
3363 {
3364 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 return;
3366 }
3367
Dino Mycle6fb96c12014-06-10 11:52:40 +05303368 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3369 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3370
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303371 context = &pHddCtx->ext_scan_context;
3372 spin_lock(&hdd_context_lock);
3373 if (context->request_id == pData->requestId) {
3374 context->response_status = pData->status ? -EINVAL : 0;
3375 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303377 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303378
3379 /*
3380 * Store the Request ID for comparing with the requestID obtained
3381 * in other requests.HDD shall return a failure is the extscan_stop
3382 * request is issued with a different requestId as that of the
3383 * extscan_start request. Also, This requestId shall be used while
3384 * indicating the full scan results to the upper layers.
3385 * The requestId is stored with the assumption that the firmware
3386 * shall return the ext scan start request's requestId in ext scan
3387 * start response.
3388 */
3389 if (pData->status == 0)
3390 pMac->sme.extScanStartReqId = pData->requestId;
3391
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303392 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303393 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303394}
3395
3396
3397static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3398{
3399 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3400 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303401 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303403 ENTER();
3404
3405 if (wlan_hdd_validate_context(pHddCtx)){
3406 return;
3407 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303408
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303409 if (!pMsg)
3410 {
3411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 return;
3413 }
3414
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303415 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3416 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303417
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303418 context = &pHddCtx->ext_scan_context;
3419 spin_lock(&hdd_context_lock);
3420 if (context->request_id == pData->requestId) {
3421 context->response_status = pData->status ? -EINVAL : 0;
3422 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303424 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303425
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303426 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303428}
3429
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3431 void *pMsg)
3432{
3433 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 tpSirEXTScanSetBssidHotListRspParams pData =
3435 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303436 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303437
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 ENTER();
3439
3440 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441 return;
3442 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303443
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303444 if (!pMsg)
3445 {
3446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3447 return;
3448 }
3449
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303450 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3451 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303453 context = &pHddCtx->ext_scan_context;
3454 spin_lock(&hdd_context_lock);
3455 if (context->request_id == pData->requestId) {
3456 context->response_status = pData->status ? -EINVAL : 0;
3457 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303459 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303461 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303462 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463}
3464
3465static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3466 void *pMsg)
3467{
3468 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 tpSirEXTScanResetBssidHotlistRspParams pData =
3470 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303471 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303473 ENTER();
3474
3475 if (wlan_hdd_validate_context(pHddCtx)) {
3476 return;
3477 }
3478 if (!pMsg)
3479 {
3480 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481 return;
3482 }
3483
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303484 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3485 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303487 context = &pHddCtx->ext_scan_context;
3488 spin_lock(&hdd_context_lock);
3489 if (context->request_id == pData->requestId) {
3490 context->response_status = pData->status ? -EINVAL : 0;
3491 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303493 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303495 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303496 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497}
3498
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3500 void *pMsg)
3501{
3502 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3503 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303504 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303505 tANI_S32 totalResults;
3506 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303507 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3508 struct hdd_ext_scan_context *context;
3509 bool ignore_cached_results = false;
3510 tExtscanCachedScanResult *result;
3511 struct nlattr *nla_results;
3512 tANI_U16 ieLength= 0;
3513 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303515 ENTER();
3516
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303517 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303519
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303520 if (!pMsg)
3521 {
3522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3523 return;
3524 }
3525
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303526 spin_lock(&hdd_context_lock);
3527 context = &pHddCtx->ext_scan_context;
3528 ignore_cached_results = context->ignore_cached_results;
3529 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303530
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303531 if (ignore_cached_results) {
3532 hddLog(LOGE,
3533 FL("Ignore the cached results received after timeout"));
3534 return;
3535 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303537 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3538 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303540 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303542 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3543 scan_id_index++) {
3544 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 totalResults = result->num_results;
3547 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3548 result->scan_id, result->flags, totalResults);
3549 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303551 do{
3552 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3553 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3554 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303556 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3557 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3558
3559 if (!skb) {
3560 hddLog(VOS_TRACE_LEVEL_ERROR,
3561 FL("cfg80211_vendor_event_alloc failed"));
3562 return;
3563 }
3564
3565 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3566
3567 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3568 pData->requestId) ||
3569 nla_put_u32(skb,
3570 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3571 resultsPerEvent)) {
3572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3573 goto fail;
3574 }
3575 if (nla_put_u8(skb,
3576 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3577 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578 {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3580 goto fail;
3581 }
3582
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303583 if (nla_put_u32(skb,
3584 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3585 result->scan_id)) {
3586 hddLog(LOGE, FL("put fail"));
3587 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303588 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303590 nla_results = nla_nest_start(skb,
3591 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3592 if (!nla_results)
3593 goto fail;
3594
3595 if (resultsPerEvent) {
3596 struct nlattr *aps;
3597 struct nlattr *nla_result;
3598
3599 nla_result = nla_nest_start(skb, scan_id_index);
3600 if(!nla_result)
3601 goto fail;
3602
3603 if (nla_put_u32(skb,
3604 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3605 result->scan_id) ||
3606 nla_put_u32(skb,
3607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3608 result->flags) ||
3609 nla_put_u32(skb,
3610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3611 totalResults)) {
3612 hddLog(LOGE, FL("put fail"));
3613 goto fail;
3614 }
3615
3616 aps = nla_nest_start(skb,
3617 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3618 if (!aps)
3619 {
3620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3621 goto fail;
3622 }
3623
3624 head_ptr = (tpSirWifiScanResult) &(result->ap);
3625
3626 for (j = 0; j < resultsPerEvent; j++, i++) {
3627 struct nlattr *ap;
3628 pSirWifiScanResult = head_ptr + i;
3629
3630 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303631 * Firmware returns timestamp from extscan_start till
3632 * BSSID was cached (in micro seconds). Add this with
3633 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303634 * to derive the time since boot when the
3635 * BSSID was cached.
3636 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303637 pSirWifiScanResult->ts +=
3638 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303639 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3640 "Ssid (%s)"
3641 "Bssid: %pM "
3642 "Channel (%u)"
3643 "Rssi (%d)"
3644 "RTT (%u)"
3645 "RTT_SD (%u)"
3646 "Beacon Period %u"
3647 "Capability 0x%x "
3648 "Ie length %d",
3649 i,
3650 pSirWifiScanResult->ts,
3651 pSirWifiScanResult->ssid,
3652 pSirWifiScanResult->bssid,
3653 pSirWifiScanResult->channel,
3654 pSirWifiScanResult->rssi,
3655 pSirWifiScanResult->rtt,
3656 pSirWifiScanResult->rtt_sd,
3657 pSirWifiScanResult->beaconPeriod,
3658 pSirWifiScanResult->capability,
3659 ieLength);
3660
3661 ap = nla_nest_start(skb, j + 1);
3662 if (!ap)
3663 {
3664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3665 goto fail;
3666 }
3667
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303668 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303669 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3670 pSirWifiScanResult->ts) )
3671 {
3672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3673 goto fail;
3674 }
3675 if (nla_put(skb,
3676 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3677 sizeof(pSirWifiScanResult->ssid),
3678 pSirWifiScanResult->ssid) )
3679 {
3680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3681 goto fail;
3682 }
3683 if (nla_put(skb,
3684 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3685 sizeof(pSirWifiScanResult->bssid),
3686 pSirWifiScanResult->bssid) )
3687 {
3688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3689 goto fail;
3690 }
3691 if (nla_put_u32(skb,
3692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3693 pSirWifiScanResult->channel) )
3694 {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3696 goto fail;
3697 }
3698 if (nla_put_s32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3700 pSirWifiScanResult->rssi) )
3701 {
3702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3703 goto fail;
3704 }
3705 if (nla_put_u32(skb,
3706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3707 pSirWifiScanResult->rtt) )
3708 {
3709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3710 goto fail;
3711 }
3712 if (nla_put_u32(skb,
3713 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3714 pSirWifiScanResult->rtt_sd))
3715 {
3716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3717 goto fail;
3718 }
3719 if (nla_put_u32(skb,
3720 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3721 pSirWifiScanResult->beaconPeriod))
3722 {
3723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3724 goto fail;
3725 }
3726 if (nla_put_u32(skb,
3727 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3728 pSirWifiScanResult->capability))
3729 {
3730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3731 goto fail;
3732 }
3733 if (nla_put_u32(skb,
3734 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3735 ieLength))
3736 {
3737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3738 goto fail;
3739 }
3740
3741 if (ieLength)
3742 if (nla_put(skb,
3743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3744 ieLength, ie)) {
3745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3746 goto fail;
3747 }
3748
3749 nla_nest_end(skb, ap);
3750 }
3751 nla_nest_end(skb, aps);
3752 nla_nest_end(skb, nla_result);
3753 }
3754
3755 nla_nest_end(skb, nla_results);
3756
3757 cfg80211_vendor_cmd_reply(skb);
3758
3759 } while (totalResults > 0);
3760 }
3761
3762 if (!pData->moreData) {
3763 spin_lock(&hdd_context_lock);
3764 context->response_status = 0;
3765 complete(&context->response_event);
3766 spin_unlock(&hdd_context_lock);
3767 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303769 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 return;
3771fail:
3772 kfree_skb(skb);
3773 return;
3774}
3775
3776static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3777 void *pMsg)
3778{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303779 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303780 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3781 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303782 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303784 ENTER();
3785
3786 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303787 hddLog(LOGE,
3788 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303789 return;
3790 }
3791 if (!pMsg)
3792 {
3793 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303794 return;
3795 }
3796
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303797 if (pData->bss_found)
3798 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3799 else
3800 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3801
Dino Mycle6fb96c12014-06-10 11:52:40 +05303802 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3804 NULL,
3805#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303806 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303807 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303808
3809 if (!skb) {
3810 hddLog(VOS_TRACE_LEVEL_ERROR,
3811 FL("cfg80211_vendor_event_alloc failed"));
3812 return;
3813 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303815 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3816 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3817 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3818 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3819
3820 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3822 "Ssid (%s) "
3823 "Bssid (" MAC_ADDRESS_STR ") "
3824 "Channel (%u) "
3825 "Rssi (%d) "
3826 "RTT (%u) "
3827 "RTT_SD (%u) ",
3828 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303829 pData->bssHotlist[i].ts,
3830 pData->bssHotlist[i].ssid,
3831 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3832 pData->bssHotlist[i].channel,
3833 pData->bssHotlist[i].rssi,
3834 pData->bssHotlist[i].rtt,
3835 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303836 }
3837
3838 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3839 pData->requestId) ||
3840 nla_put_u32(skb,
3841 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303842 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3844 goto fail;
3845 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303846 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303847 struct nlattr *aps;
3848
3849 aps = nla_nest_start(skb,
3850 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3851 if (!aps)
3852 goto fail;
3853
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303854 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303855 struct nlattr *ap;
3856
3857 ap = nla_nest_start(skb, i + 1);
3858 if (!ap)
3859 goto fail;
3860
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303861 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303862 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303863 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 nla_put(skb,
3865 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303866 sizeof(pData->bssHotlist[i].ssid),
3867 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303868 nla_put(skb,
3869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303870 sizeof(pData->bssHotlist[i].bssid),
3871 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303872 nla_put_u32(skb,
3873 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 nla_put_s32(skb,
3876 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878 nla_put_u32(skb,
3879 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303880 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303881 nla_put_u32(skb,
3882 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303883 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303884 goto fail;
3885
3886 nla_nest_end(skb, ap);
3887 }
3888 nla_nest_end(skb, aps);
3889
3890 if (nla_put_u8(skb,
3891 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3892 pData->moreData))
3893 goto fail;
3894 }
3895
3896 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303897 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303898 return;
3899
3900fail:
3901 kfree_skb(skb);
3902 return;
3903
3904}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303905
3906static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3907 void *pMsg)
3908{
3909 struct sk_buff *skb;
3910 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3911 tpSirWifiFullScanResultEvent pData =
3912 (tpSirWifiFullScanResultEvent) (pMsg);
3913
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303914 ENTER();
3915
3916 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303917 hddLog(LOGE,
3918 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303919 return;
3920 }
3921 if (!pMsg)
3922 {
3923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 return;
3925 }
3926
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303927 /*
3928 * If the full scan result including IE data exceeds NL 4K size
3929 * limitation, drop that beacon/probe rsp frame.
3930 */
3931 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3932 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3933 return;
3934 }
3935
Dino Mycle6fb96c12014-06-10 11:52:40 +05303936 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3938 NULL,
3939#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3941 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3942 GFP_KERNEL);
3943
3944 if (!skb) {
3945 hddLog(VOS_TRACE_LEVEL_ERROR,
3946 FL("cfg80211_vendor_event_alloc failed"));
3947 return;
3948 }
3949
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3951 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3952 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3953 "Ssid (%s)"
3954 "Bssid (" MAC_ADDRESS_STR ")"
3955 "Channel (%u)"
3956 "Rssi (%d)"
3957 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303958 "RTT_SD (%u)"
3959 "Bcn Period %d"
3960 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303961 pData->ap.ts,
3962 pData->ap.ssid,
3963 MAC_ADDR_ARRAY(pData->ap.bssid),
3964 pData->ap.channel,
3965 pData->ap.rssi,
3966 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303967 pData->ap.rtt_sd,
3968 pData->ap.beaconPeriod,
3969 pData->ap.capability);
3970
Dino Mycle6fb96c12014-06-10 11:52:40 +05303971 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3972 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3973 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303974 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303975 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3976 pData->ap.ts) ||
3977 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3978 sizeof(pData->ap.ssid),
3979 pData->ap.ssid) ||
3980 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3981 WNI_CFG_BSSID_LEN,
3982 pData->ap.bssid) ||
3983 nla_put_u32(skb,
3984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3985 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303986 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303987 pData->ap.rssi) ||
3988 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3989 pData->ap.rtt) ||
3990 nla_put_u32(skb,
3991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3992 pData->ap.rtt_sd) ||
3993 nla_put_u16(skb,
3994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3995 pData->ap.beaconPeriod) ||
3996 nla_put_u16(skb,
3997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3998 pData->ap.capability) ||
3999 nla_put_u32(skb,
4000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304001 pData->ieLength) ||
4002 nla_put_u8(skb,
4003 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4004 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005 {
4006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4007 goto nla_put_failure;
4008 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304009
4010 if (pData->ieLength) {
4011 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4012 pData->ieLength,
4013 pData->ie))
4014 {
4015 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4016 goto nla_put_failure;
4017 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304018 }
4019
4020 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304021 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022 return;
4023
4024nla_put_failure:
4025 kfree_skb(skb);
4026 return;
4027}
4028
4029static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4030 void *pMsg)
4031{
4032 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4033 struct sk_buff *skb = NULL;
4034 tpSirEXTScanResultsAvailableIndParams pData =
4035 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304037 ENTER();
4038
4039 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304040 hddLog(LOGE,
4041 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304042 return;
4043 }
4044 if (!pMsg)
4045 {
4046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304047 return;
4048 }
4049
4050 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4052 NULL,
4053#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4055 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4056 GFP_KERNEL);
4057
4058 if (!skb) {
4059 hddLog(VOS_TRACE_LEVEL_ERROR,
4060 FL("cfg80211_vendor_event_alloc failed"));
4061 return;
4062 }
4063
Dino Mycle6fb96c12014-06-10 11:52:40 +05304064 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4065 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4066 pData->numResultsAvailable);
4067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4068 pData->requestId) ||
4069 nla_put_u32(skb,
4070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4071 pData->numResultsAvailable)) {
4072 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4073 goto nla_put_failure;
4074 }
4075
4076 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304077 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304078 return;
4079
4080nla_put_failure:
4081 kfree_skb(skb);
4082 return;
4083}
4084
4085static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4086{
4087 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4088 struct sk_buff *skb = NULL;
4089 tpSirEXTScanProgressIndParams pData =
4090 (tpSirEXTScanProgressIndParams) pMsg;
4091
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304092 ENTER();
4093
4094 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304095 hddLog(LOGE,
4096 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304097 return;
4098 }
4099 if (!pMsg)
4100 {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304102 return;
4103 }
4104
4105 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4107 NULL,
4108#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304109 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4110 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4111 GFP_KERNEL);
4112
4113 if (!skb) {
4114 hddLog(VOS_TRACE_LEVEL_ERROR,
4115 FL("cfg80211_vendor_event_alloc failed"));
4116 return;
4117 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304118 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304119 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4120 pData->extScanEventType);
4121 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4122 pData->status);
4123
4124 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4125 pData->extScanEventType) ||
4126 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304127 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4128 pData->requestId) ||
4129 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304130 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4131 pData->status)) {
4132 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4133 goto nla_put_failure;
4134 }
4135
4136 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304137 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304138 return;
4139
4140nla_put_failure:
4141 kfree_skb(skb);
4142 return;
4143}
4144
4145void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4146 void *pMsg)
4147{
4148 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4149
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304150 ENTER();
4151
Dino Mycle6fb96c12014-06-10 11:52:40 +05304152 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304153 return;
4154 }
4155
4156 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4157
4158
4159 switch(evType) {
4160 case SIR_HAL_EXTSCAN_START_RSP:
4161 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4162 break;
4163
4164 case SIR_HAL_EXTSCAN_STOP_RSP:
4165 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4166 break;
4167 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4168 /* There is no need to send this response to upper layer
4169 Just log the message */
4170 hddLog(VOS_TRACE_LEVEL_INFO,
4171 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4172 break;
4173 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4174 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4175 break;
4176
4177 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4178 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4179 break;
4180
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304182 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304183 break;
4184 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4185 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4186 break;
4187 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4188 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4189 break;
4190 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4191 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4192 break;
4193 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4194 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4195 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4197 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4198 break;
4199 default:
4200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4201 break;
4202 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304203 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204}
4205
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304206static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4207 struct wireless_dev *wdev,
4208 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209{
Dino Myclee8843b32014-07-04 14:21:45 +05304210 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304211 struct net_device *dev = wdev->netdev;
4212 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4213 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4214 struct nlattr
4215 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4216 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304217 struct hdd_ext_scan_context *context;
4218 unsigned long rc;
4219 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304221 ENTER();
4222
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 status = wlan_hdd_validate_context(pHddCtx);
4224 if (0 != status)
4225 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304226 return -EINVAL;
4227 }
Dino Myclee8843b32014-07-04 14:21:45 +05304228 /* check the EXTScan Capability */
4229 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304230 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4231 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304232 {
4233 hddLog(VOS_TRACE_LEVEL_ERROR,
4234 FL("EXTScan not enabled/supported by Firmware"));
4235 return -EINVAL;
4236 }
4237
Dino Mycle6fb96c12014-06-10 11:52:40 +05304238 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4239 data, dataLen,
4240 wlan_hdd_extscan_config_policy)) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4242 return -EINVAL;
4243 }
4244
4245 /* Parse and fetch request Id */
4246 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4248 return -EINVAL;
4249 }
4250
Dino Myclee8843b32014-07-04 14:21:45 +05304251 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304253 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304254
Dino Myclee8843b32014-07-04 14:21:45 +05304255 reqMsg.sessionId = pAdapter->sessionId;
4256 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304258 vos_spin_lock_acquire(&hdd_context_lock);
4259 context = &pHddCtx->ext_scan_context;
4260 context->request_id = reqMsg.requestId;
4261 INIT_COMPLETION(context->response_event);
4262 vos_spin_lock_release(&hdd_context_lock);
4263
Dino Myclee8843b32014-07-04 14:21:45 +05304264 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304265 if (!HAL_STATUS_SUCCESS(status)) {
4266 hddLog(VOS_TRACE_LEVEL_ERROR,
4267 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304268 return -EINVAL;
4269 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304270
4271 rc = wait_for_completion_timeout(&context->response_event,
4272 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4273 if (!rc) {
4274 hddLog(LOGE, FL("Target response timed out"));
4275 return -ETIMEDOUT;
4276 }
4277
4278 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4279 if (ret)
4280 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4281
4282 return ret;
4283
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304284 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304285 return 0;
4286}
4287
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304288static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4289 struct wireless_dev *wdev,
4290 const void *data, int dataLen)
4291{
4292 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304293
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304294 vos_ssr_protect(__func__);
4295 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4296 vos_ssr_unprotect(__func__);
4297
4298 return ret;
4299}
4300
4301static int __wlan_hdd_cfg80211_extscan_get_cached_results(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 tSirEXTScanGetCachedResultsReqParams 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 Kumare1b8a942015-08-25 12:44:24 +05304312 struct hdd_ext_scan_context *context;
4313 unsigned long rc;
4314 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ENTER();
4317
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304318 if (VOS_FTM_MODE == hdd_get_conparam()) {
4319 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4320 return -EINVAL;
4321 }
4322
Dino Mycle6fb96c12014-06-10 11:52:40 +05304323 status = wlan_hdd_validate_context(pHddCtx);
4324 if (0 != status)
4325 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326 return -EINVAL;
4327 }
Dino Myclee8843b32014-07-04 14:21:45 +05304328 /* check the EXTScan Capability */
4329 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304330 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4331 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304332 {
4333 hddLog(VOS_TRACE_LEVEL_ERROR,
4334 FL("EXTScan not enabled/supported by Firmware"));
4335 return -EINVAL;
4336 }
4337
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4339 data, dataLen,
4340 wlan_hdd_extscan_config_policy)) {
4341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4342 return -EINVAL;
4343 }
4344 /* Parse and fetch request Id */
4345 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4347 return -EINVAL;
4348 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304351 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4352
Dino Myclee8843b32014-07-04 14:21:45 +05304353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354
Dino Myclee8843b32014-07-04 14:21:45 +05304355 reqMsg.sessionId = pAdapter->sessionId;
4356 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357
4358 /* Parse and fetch flush parameter */
4359 if (!tb
4360 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4361 {
4362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4363 goto failed;
4364 }
Dino Myclee8843b32014-07-04 14:21:45 +05304365 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4367
Dino Myclee8843b32014-07-04 14:21:45 +05304368 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304369
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304370 spin_lock(&hdd_context_lock);
4371 context = &pHddCtx->ext_scan_context;
4372 context->request_id = reqMsg.requestId;
4373 context->ignore_cached_results = false;
4374 INIT_COMPLETION(context->response_event);
4375 spin_unlock(&hdd_context_lock);
4376
Dino Myclee8843b32014-07-04 14:21:45 +05304377 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304378 if (!HAL_STATUS_SUCCESS(status)) {
4379 hddLog(VOS_TRACE_LEVEL_ERROR,
4380 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304381 return -EINVAL;
4382 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304383
4384 rc = wait_for_completion_timeout(&context->response_event,
4385 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4386 if (!rc) {
4387 hddLog(LOGE, FL("Target response timed out"));
4388 retval = -ETIMEDOUT;
4389 spin_lock(&hdd_context_lock);
4390 context->ignore_cached_results = true;
4391 spin_unlock(&hdd_context_lock);
4392 } else {
4393 spin_lock(&hdd_context_lock);
4394 retval = context->response_status;
4395 spin_unlock(&hdd_context_lock);
4396 }
4397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304398 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304399 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304400
4401failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304402 return -EINVAL;
4403}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304404static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4405 struct wireless_dev *wdev,
4406 const void *data, int dataLen)
4407{
4408 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304410 vos_ssr_protect(__func__);
4411 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4412 vos_ssr_unprotect(__func__);
4413
4414 return ret;
4415}
4416
4417static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304419 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304420{
4421 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4422 struct net_device *dev = wdev->netdev;
4423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4424 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4425 struct nlattr
4426 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4427 struct nlattr
4428 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4429 struct nlattr *apTh;
4430 eHalStatus status;
4431 tANI_U8 i = 0;
4432 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304433 struct hdd_ext_scan_context *context;
4434 tANI_U32 request_id;
4435 unsigned long rc;
4436 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304437
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304438 ENTER();
4439
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304440 if (VOS_FTM_MODE == hdd_get_conparam()) {
4441 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4442 return -EINVAL;
4443 }
4444
Dino Mycle6fb96c12014-06-10 11:52:40 +05304445 status = wlan_hdd_validate_context(pHddCtx);
4446 if (0 != status)
4447 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304448 return -EINVAL;
4449 }
Dino Myclee8843b32014-07-04 14:21:45 +05304450 /* check the EXTScan Capability */
4451 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304452 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4453 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304454 {
4455 hddLog(VOS_TRACE_LEVEL_ERROR,
4456 FL("EXTScan not enabled/supported by Firmware"));
4457 return -EINVAL;
4458 }
4459
Dino Mycle6fb96c12014-06-10 11:52:40 +05304460 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4461 data, dataLen,
4462 wlan_hdd_extscan_config_policy)) {
4463 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4464 return -EINVAL;
4465 }
4466
4467 /* Parse and fetch request Id */
4468 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4469 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4470 return -EINVAL;
4471 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304472 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4473 vos_mem_malloc(sizeof(*pReqMsg));
4474 if (!pReqMsg) {
4475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4476 return -ENOMEM;
4477 }
4478
Dino Myclee8843b32014-07-04 14:21:45 +05304479
Dino Mycle6fb96c12014-06-10 11:52:40 +05304480 pReqMsg->requestId = nla_get_u32(
4481 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4483
4484 /* Parse and fetch number of APs */
4485 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4487 goto fail;
4488 }
4489
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304490 /* Parse and fetch lost ap sample size */
4491 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4492 hddLog(LOGE, FL("attr lost ap sample size failed"));
4493 goto fail;
4494 }
4495
4496 pReqMsg->lostBssidSampleSize = nla_get_u32(
4497 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4498 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4499
Dino Mycle6fb96c12014-06-10 11:52:40 +05304500 pReqMsg->sessionId = pAdapter->sessionId;
4501 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4502
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304503 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304505 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4506 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4507 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4508 goto fail;
4509 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304510 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304511
4512 nla_for_each_nested(apTh,
4513 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304514 if (i == pReqMsg->numBssid) {
4515 hddLog(LOGW, FL("Ignoring excess AP"));
4516 break;
4517 }
4518
Dino Mycle6fb96c12014-06-10 11:52:40 +05304519 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4520 nla_data(apTh), nla_len(apTh),
4521 NULL)) {
4522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4523 goto fail;
4524 }
4525
4526 /* Parse and fetch MAC address */
4527 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4529 goto fail;
4530 }
4531 memcpy(pReqMsg->ap[i].bssid, nla_data(
4532 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4533 sizeof(tSirMacAddr));
4534 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4535
4536 /* Parse and fetch low RSSI */
4537 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4538 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4539 goto fail;
4540 }
4541 pReqMsg->ap[i].low = nla_get_s32(
4542 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4543 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4544
4545 /* Parse and fetch high RSSI */
4546 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4547 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4548 goto fail;
4549 }
4550 pReqMsg->ap[i].high = nla_get_s32(
4551 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4552 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4553 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304554 i++;
4555 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304556
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304557 if (i < pReqMsg->numBssid) {
4558 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4559 i, pReqMsg->numBssid);
4560 pReqMsg->numBssid = i;
4561 }
4562
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304563 context = &pHddCtx->ext_scan_context;
4564 spin_lock(&hdd_context_lock);
4565 INIT_COMPLETION(context->response_event);
4566 context->request_id = request_id = pReqMsg->requestId;
4567 spin_unlock(&hdd_context_lock);
4568
Dino Mycle6fb96c12014-06-10 11:52:40 +05304569 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4570 if (!HAL_STATUS_SUCCESS(status)) {
4571 hddLog(VOS_TRACE_LEVEL_ERROR,
4572 FL("sme_SetBssHotlist failed(err=%d)"), status);
4573 vos_mem_free(pReqMsg);
4574 return -EINVAL;
4575 }
4576
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304577 /* request was sent -- wait for the response */
4578 rc = wait_for_completion_timeout(&context->response_event,
4579 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4580
4581 if (!rc) {
4582 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4583 retval = -ETIMEDOUT;
4584 } else {
4585 spin_lock(&hdd_context_lock);
4586 if (context->request_id == request_id)
4587 retval = context->response_status;
4588 else
4589 retval = -EINVAL;
4590 spin_unlock(&hdd_context_lock);
4591 }
4592
Dino Myclee8843b32014-07-04 14:21:45 +05304593 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304594 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304595 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304596
4597fail:
4598 vos_mem_free(pReqMsg);
4599 return -EINVAL;
4600}
4601
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304602static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4603 struct wireless_dev *wdev,
4604 const void *data, int dataLen)
4605{
4606 int ret = 0;
4607
4608 vos_ssr_protect(__func__);
4609 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4610 dataLen);
4611 vos_ssr_unprotect(__func__);
4612
4613 return ret;
4614}
4615
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304616static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304618 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304620 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4621 struct net_device *dev = wdev->netdev;
4622 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4623 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4624 uint8_t num_channels = 0;
4625 uint8_t num_chan_new = 0;
4626 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304628 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 tWifiBand wifiBand;
4630 eHalStatus status;
4631 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304632 tANI_U8 i,j,k;
4633 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304634
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304635 ENTER();
4636
Dino Mycle6fb96c12014-06-10 11:52:40 +05304637 status = wlan_hdd_validate_context(pHddCtx);
4638 if (0 != status)
4639 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304640 return -EINVAL;
4641 }
Dino Myclee8843b32014-07-04 14:21:45 +05304642
Dino Mycle6fb96c12014-06-10 11:52:40 +05304643 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4644 data, dataLen,
4645 wlan_hdd_extscan_config_policy)) {
4646 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4647 return -EINVAL;
4648 }
4649
4650 /* Parse and fetch request Id */
4651 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4653 return -EINVAL;
4654 }
4655 requestId = nla_get_u32(
4656 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4657 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4658
4659 /* Parse and fetch wifi band */
4660 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4661 {
4662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4663 return -EINVAL;
4664 }
4665 wifiBand = nla_get_u32(
4666 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4667 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4668
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304669 /* Parse and fetch max channels */
4670 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4671 {
4672 hddLog(LOGE, FL("attr max channels failed"));
4673 return -EINVAL;
4674 }
4675 maxChannels = nla_get_u32(
4676 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4678
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304680 wifiBand, chan_list,
4681 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 if (eHAL_STATUS_SUCCESS != status) {
4683 hddLog(VOS_TRACE_LEVEL_ERROR,
4684 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4685 return -EINVAL;
4686 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304687
Agrawal Ashish16abf782016-08-18 22:42:59 +05304688 num_channels = VOS_MIN(num_channels, maxChannels);
4689 num_chan_new = num_channels;
4690 /* remove the indoor only channels if iface is SAP */
4691 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4692 {
4693 num_chan_new = 0;
4694 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304695 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304696 if (wiphy->bands[j] == NULL)
4697 continue;
4698 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4699 if ((chan_list[i] ==
4700 wiphy->bands[j]->channels[k].center_freq) &&
4701 (!(wiphy->bands[j]->channels[k].flags &
4702 IEEE80211_CHAN_INDOOR_ONLY))) {
4703 chan_list[num_chan_new] = chan_list[i];
4704 num_chan_new++;
4705 }
4706 }
4707 }
4708 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304709
Agrawal Ashish16abf782016-08-18 22:42:59 +05304710 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4711 for (i = 0; i < num_chan_new; i++)
4712 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4713 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714
4715 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304716 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304717 NLMSG_HDRLEN);
4718
4719 if (!replySkb) {
4720 hddLog(VOS_TRACE_LEVEL_ERROR,
4721 FL("valid channels: buffer alloc fail"));
4722 return -EINVAL;
4723 }
4724 if (nla_put_u32(replySkb,
4725 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304726 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304727 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304728 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
4730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4731 kfree_skb(replySkb);
4732 return -EINVAL;
4733 }
4734
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304735 ret = cfg80211_vendor_cmd_reply(replySkb);
4736
4737 EXIT();
4738 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739}
4740
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304741static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4742 struct wireless_dev *wdev,
4743 const void *data, int dataLen)
4744{
4745 int ret = 0;
4746
4747 vos_ssr_protect(__func__);
4748 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4749 dataLen);
4750 vos_ssr_unprotect(__func__);
4751
4752 return ret;
4753}
4754
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304755static int hdd_extscan_start_fill_bucket_channel_spec(
4756 hdd_context_t *pHddCtx,
4757 tpSirEXTScanStartReqParams pReqMsg,
4758 struct nlattr **tb)
4759{
4760 struct nlattr *bucket[
4761 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4762 struct nlattr *channel[
4763 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4764 struct nlattr *buckets;
4765 struct nlattr *channels;
4766 int rem1, rem2;
4767 eHalStatus status;
4768 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304769 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304770 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4771 tANI_U32 passive_max_chn_time, active_max_chn_time;
4772
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304773 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304774 bktIndex = 0;
4775
4776 nla_for_each_nested(buckets,
4777 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304778 if (bktIndex >= expected_buckets) {
4779 hddLog(LOGW, FL("ignoring excess buckets"));
4780 break;
4781 }
4782
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304783 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304784 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4785 nla_data(buckets), nla_len(buckets),
4786 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304787 hddLog(LOGE, FL("nla_parse failed"));
4788 return -EINVAL;
4789 }
4790
4791 /* Parse and fetch bucket spec */
4792 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4793 hddLog(LOGE, FL("attr bucket index failed"));
4794 return -EINVAL;
4795 }
4796 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4797 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4798 hddLog(LOG1, FL("Bucket spec Index %d"),
4799 pReqMsg->buckets[bktIndex].bucket);
4800
4801 /* Parse and fetch wifi band */
4802 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4803 hddLog(LOGE, FL("attr wifi band failed"));
4804 return -EINVAL;
4805 }
4806 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4807 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4808 hddLog(LOG1, FL("Wifi band %d"),
4809 pReqMsg->buckets[bktIndex].band);
4810
4811 /* Parse and fetch period */
4812 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4813 hddLog(LOGE, FL("attr period failed"));
4814 return -EINVAL;
4815 }
4816 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4817 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4818 hddLog(LOG1, FL("period %d"),
4819 pReqMsg->buckets[bktIndex].period);
4820
4821 /* Parse and fetch report events */
4822 if (!bucket[
4823 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4824 hddLog(LOGE, FL("attr report events failed"));
4825 return -EINVAL;
4826 }
4827 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4828 bucket[
4829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4830 hddLog(LOG1, FL("report events %d"),
4831 pReqMsg->buckets[bktIndex].reportEvents);
4832
4833 /* Parse and fetch max period */
4834 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4835 hddLog(LOGE, FL("attr max period failed"));
4836 return -EINVAL;
4837 }
4838 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4839 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4840 hddLog(LOG1, FL("max period %u"),
4841 pReqMsg->buckets[bktIndex].max_period);
4842
4843 /* Parse and fetch exponent */
4844 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4845 hddLog(LOGE, FL("attr exponent failed"));
4846 return -EINVAL;
4847 }
4848 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4849 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4850 hddLog(LOG1, FL("exponent %u"),
4851 pReqMsg->buckets[bktIndex].exponent);
4852
4853 /* Parse and fetch step count */
4854 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4855 hddLog(LOGE, FL("attr step count failed"));
4856 return -EINVAL;
4857 }
4858 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4859 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4860 hddLog(LOG1, FL("Step count %u"),
4861 pReqMsg->buckets[bktIndex].step_count);
4862
4863 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4864 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4865
4866 /* Framework shall pass the channel list if the input WiFi band is
4867 * WIFI_BAND_UNSPECIFIED.
4868 * If the input WiFi band is specified (any value other than
4869 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4870 */
4871 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4872 numChannels = 0;
4873 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4874 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4875 pReqMsg->buckets[bktIndex].band,
4876 chanList, &numChannels);
4877 if (!HAL_STATUS_SUCCESS(status)) {
4878 hddLog(LOGE,
4879 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4880 status);
4881 return -EINVAL;
4882 }
4883
4884 pReqMsg->buckets[bktIndex].numChannels =
4885 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4886 hddLog(LOG1, FL("Num channels %d"),
4887 pReqMsg->buckets[bktIndex].numChannels);
4888
4889 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4890 j++) {
4891 pReqMsg->buckets[bktIndex].channels[j].channel =
4892 chanList[j];
4893 pReqMsg->buckets[bktIndex].channels[j].
4894 chnlClass = 0;
4895 if (CSR_IS_CHANNEL_DFS(
4896 vos_freq_to_chan(chanList[j]))) {
4897 pReqMsg->buckets[bktIndex].channels[j].
4898 passive = 1;
4899 pReqMsg->buckets[bktIndex].channels[j].
4900 dwellTimeMs = passive_max_chn_time;
4901 } else {
4902 pReqMsg->buckets[bktIndex].channels[j].
4903 passive = 0;
4904 pReqMsg->buckets[bktIndex].channels[j].
4905 dwellTimeMs = active_max_chn_time;
4906 }
4907
4908 hddLog(LOG1,
4909 "Channel %u Passive %u Dwell time %u ms",
4910 pReqMsg->buckets[bktIndex].channels[j].channel,
4911 pReqMsg->buckets[bktIndex].channels[j].passive,
4912 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4913 }
4914
4915 bktIndex++;
4916 continue;
4917 }
4918
4919 /* Parse and fetch number of channels */
4920 if (!bucket[
4921 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4922 hddLog(LOGE, FL("attr num channels failed"));
4923 return -EINVAL;
4924 }
4925
4926 pReqMsg->buckets[bktIndex].numChannels =
4927 nla_get_u32(bucket[
4928 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4929 hddLog(LOG1, FL("num channels %d"),
4930 pReqMsg->buckets[bktIndex].numChannels);
4931
4932 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4933 hddLog(LOGE, FL("attr channel spec failed"));
4934 return -EINVAL;
4935 }
4936
4937 j = 0;
4938 nla_for_each_nested(channels,
4939 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4940 if (nla_parse(channel,
4941 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4942 nla_data(channels), nla_len(channels),
4943 wlan_hdd_extscan_config_policy)) {
4944 hddLog(LOGE, FL("nla_parse failed"));
4945 return -EINVAL;
4946 }
4947
4948 /* Parse and fetch channel */
4949 if (!channel[
4950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4951 hddLog(LOGE, FL("attr channel failed"));
4952 return -EINVAL;
4953 }
4954 pReqMsg->buckets[bktIndex].channels[j].channel =
4955 nla_get_u32(channel[
4956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4957 hddLog(LOG1, FL("channel %u"),
4958 pReqMsg->buckets[bktIndex].channels[j].channel);
4959
4960 /* Parse and fetch dwell time */
4961 if (!channel[
4962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4963 hddLog(LOGE, FL("attr dwelltime failed"));
4964 return -EINVAL;
4965 }
4966 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4967 nla_get_u32(channel[
4968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4969
4970 hddLog(LOG1, FL("Dwell time (%u ms)"),
4971 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4972
4973
4974 /* Parse and fetch channel spec passive */
4975 if (!channel[
4976 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4977 hddLog(LOGE,
4978 FL("attr channel spec passive failed"));
4979 return -EINVAL;
4980 }
4981 pReqMsg->buckets[bktIndex].channels[j].passive =
4982 nla_get_u8(channel[
4983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4984 hddLog(LOG1, FL("Chnl spec passive %u"),
4985 pReqMsg->buckets[bktIndex].channels[j].passive);
4986
4987 j++;
4988 }
4989
4990 bktIndex++;
4991 }
4992
4993 return 0;
4994}
4995
4996
4997/*
4998 * define short names for the global vendor params
4999 * used by wlan_hdd_cfg80211_extscan_start()
5000 */
5001#define PARAM_MAX \
5002QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5003#define PARAM_REQUEST_ID \
5004QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5005#define PARAM_BASE_PERIOD \
5006QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5007#define PARAM_MAX_AP_PER_SCAN \
5008QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5009#define PARAM_RPT_THRHLD_PERCENT \
5010QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5011#define PARAM_RPT_THRHLD_NUM_SCANS \
5012QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5013#define PARAM_NUM_BUCKETS \
5014QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5015
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305016static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305017 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305018 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305019{
Dino Myclee8843b32014-07-04 14:21:45 +05305020 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305021 struct net_device *dev = wdev->netdev;
5022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5023 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5024 struct nlattr *tb[PARAM_MAX + 1];
5025 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305026 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305027 tANI_U32 request_id;
5028 struct hdd_ext_scan_context *context;
5029 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305030
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305031 ENTER();
5032
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305033 if (VOS_FTM_MODE == hdd_get_conparam()) {
5034 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5035 return -EINVAL;
5036 }
5037
Dino Mycle6fb96c12014-06-10 11:52:40 +05305038 status = wlan_hdd_validate_context(pHddCtx);
5039 if (0 != status)
5040 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305041 return -EINVAL;
5042 }
Dino Myclee8843b32014-07-04 14:21:45 +05305043 /* check the EXTScan Capability */
5044 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305045 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5046 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305047 {
5048 hddLog(VOS_TRACE_LEVEL_ERROR,
5049 FL("EXTScan not enabled/supported by Firmware"));
5050 return -EINVAL;
5051 }
5052
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305053 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305054 data, dataLen,
5055 wlan_hdd_extscan_config_policy)) {
5056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5057 return -EINVAL;
5058 }
5059
5060 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305061 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305062 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5063 return -EINVAL;
5064 }
5065
Dino Myclee8843b32014-07-04 14:21:45 +05305066 pReqMsg = (tpSirEXTScanStartReqParams)
5067 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305068 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5070 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305071 }
5072
5073 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305074 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305075 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5076
5077 pReqMsg->sessionId = pAdapter->sessionId;
5078 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5079
5080 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305081 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5083 goto fail;
5084 }
5085 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305086 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305087 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5088 pReqMsg->basePeriod);
5089
5090 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305091 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5093 goto fail;
5094 }
5095 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305096 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305097 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5098 pReqMsg->maxAPperScan);
5099
5100 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305101 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5103 goto fail;
5104 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305105 pReqMsg->reportThresholdPercent = nla_get_u8(
5106 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305107 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305108 pReqMsg->reportThresholdPercent);
5109
5110 /* Parse and fetch report threshold num scans */
5111 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5112 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5113 goto fail;
5114 }
5115 pReqMsg->reportThresholdNumScans = nla_get_u8(
5116 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5117 hddLog(LOG1, FL("Report Threshold num scans %d"),
5118 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305119
5120 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305121 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305122 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5123 goto fail;
5124 }
5125 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305126 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305127 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5128 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5129 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5130 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5131 }
5132 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5133 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305134
Dino Mycle6fb96c12014-06-10 11:52:40 +05305135 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5137 goto fail;
5138 }
5139
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305140 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305141
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305142 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5143 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305144
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305145 context = &pHddCtx->ext_scan_context;
5146 spin_lock(&hdd_context_lock);
5147 INIT_COMPLETION(context->response_event);
5148 context->request_id = request_id = pReqMsg->requestId;
5149 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305150
Dino Mycle6fb96c12014-06-10 11:52:40 +05305151 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5152 if (!HAL_STATUS_SUCCESS(status)) {
5153 hddLog(VOS_TRACE_LEVEL_ERROR,
5154 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305155 goto fail;
5156 }
5157
Srinivas Dasari91727c12016-03-23 17:59:06 +05305158 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5159
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305160 /* request was sent -- wait for the response */
5161 rc = wait_for_completion_timeout(&context->response_event,
5162 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5163
5164 if (!rc) {
5165 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5166 retval = -ETIMEDOUT;
5167 } else {
5168 spin_lock(&hdd_context_lock);
5169 if (context->request_id == request_id)
5170 retval = context->response_status;
5171 else
5172 retval = -EINVAL;
5173 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174 }
5175
Dino Myclee8843b32014-07-04 14:21:45 +05305176 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305177 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305178 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305179
5180fail:
5181 vos_mem_free(pReqMsg);
5182 return -EINVAL;
5183}
5184
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305185/*
5186 * done with short names for the global vendor params
5187 * used by wlan_hdd_cfg80211_extscan_start()
5188 */
5189#undef PARAM_MAX
5190#undef PARAM_REQUEST_ID
5191#undef PARAM_BASE_PERIOD
5192#undef PARAMS_MAX_AP_PER_SCAN
5193#undef PARAMS_RPT_THRHLD_PERCENT
5194#undef PARAMS_RPT_THRHLD_NUM_SCANS
5195#undef PARAMS_NUM_BUCKETS
5196
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305197static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5198 struct wireless_dev *wdev,
5199 const void *data, int dataLen)
5200{
5201 int ret = 0;
5202
5203 vos_ssr_protect(__func__);
5204 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5205 vos_ssr_unprotect(__func__);
5206
5207 return ret;
5208}
5209
5210static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305212 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305213{
Dino Myclee8843b32014-07-04 14:21:45 +05305214 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305215 struct net_device *dev = wdev->netdev;
5216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5217 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5218 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5219 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305220 int retval;
5221 unsigned long rc;
5222 struct hdd_ext_scan_context *context;
5223 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305224
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305225 ENTER();
5226
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305227 if (VOS_FTM_MODE == hdd_get_conparam()) {
5228 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5229 return -EINVAL;
5230 }
5231
Dino Mycle6fb96c12014-06-10 11:52:40 +05305232 status = wlan_hdd_validate_context(pHddCtx);
5233 if (0 != status)
5234 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305235 return -EINVAL;
5236 }
Dino Myclee8843b32014-07-04 14:21:45 +05305237 /* check the EXTScan Capability */
5238 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305239 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5240 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305241 {
5242 hddLog(VOS_TRACE_LEVEL_ERROR,
5243 FL("EXTScan not enabled/supported by Firmware"));
5244 return -EINVAL;
5245 }
5246
Dino Mycle6fb96c12014-06-10 11:52:40 +05305247 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5248 data, dataLen,
5249 wlan_hdd_extscan_config_policy)) {
5250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5251 return -EINVAL;
5252 }
5253
5254 /* Parse and fetch request Id */
5255 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5257 return -EINVAL;
5258 }
5259
Dino Myclee8843b32014-07-04 14:21:45 +05305260 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305261 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305263
Dino Myclee8843b32014-07-04 14:21:45 +05305264 reqMsg.sessionId = pAdapter->sessionId;
5265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305266
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305267 context = &pHddCtx->ext_scan_context;
5268 spin_lock(&hdd_context_lock);
5269 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305270 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305271 spin_unlock(&hdd_context_lock);
5272
Dino Myclee8843b32014-07-04 14:21:45 +05305273 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305274 if (!HAL_STATUS_SUCCESS(status)) {
5275 hddLog(VOS_TRACE_LEVEL_ERROR,
5276 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305277 return -EINVAL;
5278 }
5279
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305280 /* request was sent -- wait for the response */
5281 rc = wait_for_completion_timeout(&context->response_event,
5282 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5283
5284 if (!rc) {
5285 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5286 retval = -ETIMEDOUT;
5287 } else {
5288 spin_lock(&hdd_context_lock);
5289 if (context->request_id == request_id)
5290 retval = context->response_status;
5291 else
5292 retval = -EINVAL;
5293 spin_unlock(&hdd_context_lock);
5294 }
5295
5296 return retval;
5297
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305299 return 0;
5300}
5301
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305302static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5303 struct wireless_dev *wdev,
5304 const void *data, int dataLen)
5305{
5306 int ret = 0;
5307
5308 vos_ssr_protect(__func__);
5309 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5310 vos_ssr_unprotect(__func__);
5311
5312 return ret;
5313}
5314
5315static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305316 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305317 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305318{
Dino Myclee8843b32014-07-04 14:21:45 +05305319 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305320 struct net_device *dev = wdev->netdev;
5321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5322 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5323 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5324 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305325 struct hdd_ext_scan_context *context;
5326 tANI_U32 request_id;
5327 unsigned long rc;
5328 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305330 ENTER();
5331
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305332 if (VOS_FTM_MODE == hdd_get_conparam()) {
5333 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5334 return -EINVAL;
5335 }
5336
Dino Mycle6fb96c12014-06-10 11:52:40 +05305337 status = wlan_hdd_validate_context(pHddCtx);
5338 if (0 != status)
5339 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305340 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305341 return -EINVAL;
5342 }
Dino Myclee8843b32014-07-04 14:21:45 +05305343 /* check the EXTScan Capability */
5344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5346 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305347 {
5348 hddLog(VOS_TRACE_LEVEL_ERROR,
5349 FL("EXTScan not enabled/supported by Firmware"));
5350 return -EINVAL;
5351 }
5352
Dino Mycle6fb96c12014-06-10 11:52:40 +05305353 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5354 data, dataLen,
5355 wlan_hdd_extscan_config_policy)) {
5356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5357 return -EINVAL;
5358 }
5359
5360 /* Parse and fetch request Id */
5361 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5363 return -EINVAL;
5364 }
5365
Dino Myclee8843b32014-07-04 14:21:45 +05305366 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305368 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369
Dino Myclee8843b32014-07-04 14:21:45 +05305370 reqMsg.sessionId = pAdapter->sessionId;
5371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305373 context = &pHddCtx->ext_scan_context;
5374 spin_lock(&hdd_context_lock);
5375 INIT_COMPLETION(context->response_event);
5376 context->request_id = request_id = reqMsg.requestId;
5377 spin_unlock(&hdd_context_lock);
5378
Dino Myclee8843b32014-07-04 14:21:45 +05305379 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305380 if (!HAL_STATUS_SUCCESS(status)) {
5381 hddLog(VOS_TRACE_LEVEL_ERROR,
5382 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305383 return -EINVAL;
5384 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305385
5386 /* request was sent -- wait for the response */
5387 rc = wait_for_completion_timeout(&context->response_event,
5388 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5389 if (!rc) {
5390 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5391 retval = -ETIMEDOUT;
5392 } else {
5393 spin_lock(&hdd_context_lock);
5394 if (context->request_id == request_id)
5395 retval = context->response_status;
5396 else
5397 retval = -EINVAL;
5398 spin_unlock(&hdd_context_lock);
5399 }
5400
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305401 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305402 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305403}
5404
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305405static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5406 struct wireless_dev *wdev,
5407 const void *data, int dataLen)
5408{
5409 int ret = 0;
5410
5411 vos_ssr_protect(__func__);
5412 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5413 vos_ssr_unprotect(__func__);
5414
5415 return ret;
5416}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305417#endif /* WLAN_FEATURE_EXTSCAN */
5418
Atul Mittal115287b2014-07-08 13:26:33 +05305419/*EXT TDLS*/
5420static const struct nla_policy
5421wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5422{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305423 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5424 .type = NLA_UNSPEC,
5425 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305426 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5427 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5428 {.type = NLA_S32 },
5429 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5430 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5431
5432};
5433
5434static const struct nla_policy
5435wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5436{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305437 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5438 .type = NLA_UNSPEC,
5439 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305440
5441};
5442
5443static const struct nla_policy
5444wlan_hdd_tdls_config_state_change_policy[
5445 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5446{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305447 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5448 .type = NLA_UNSPEC,
5449 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305450 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5451 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305452 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5453 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5454 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305455
5456};
5457
5458static const struct nla_policy
5459wlan_hdd_tdls_config_get_status_policy[
5460 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5461{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305462 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5463 .type = NLA_UNSPEC,
5464 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305465 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5466 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305467 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5468 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5469 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305470
5471};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305472
5473static const struct nla_policy
5474wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5475{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305476 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5477 .type = NLA_UNSPEC,
5478 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305479};
5480
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305481static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305482 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305483 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305484 int data_len)
5485{
5486
5487 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5488 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305490 ENTER();
5491
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305492 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305493 return -EINVAL;
5494 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305495 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305496 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305497 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305498 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305499 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305500 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305501 return -ENOTSUPP;
5502 }
5503
5504 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5505 data, data_len, wlan_hdd_mac_config)) {
5506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5507 return -EINVAL;
5508 }
5509
5510 /* Parse and fetch mac address */
5511 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5513 return -EINVAL;
5514 }
5515
5516 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5517 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5518 VOS_MAC_ADDR_LAST_3_BYTES);
5519
Siddharth Bhal76972212014-10-15 16:22:51 +05305520 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5521
5522 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305523 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5524 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305525 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5526 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5527 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5528 {
5529 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5530 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5531 VOS_MAC_ADDRESS_LEN);
5532 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305533 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305534
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305535 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5536 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305537
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305538 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305539 return 0;
5540}
5541
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305542static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5543 struct wireless_dev *wdev,
5544 const void *data,
5545 int data_len)
5546{
5547 int ret = 0;
5548
5549 vos_ssr_protect(__func__);
5550 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5551 vos_ssr_unprotect(__func__);
5552
5553 return ret;
5554}
5555
5556static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305557 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305558 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305559 int data_len)
5560{
5561 u8 peer[6] = {0};
5562 struct net_device *dev = wdev->netdev;
5563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5564 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5565 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5566 eHalStatus ret;
5567 tANI_S32 state;
5568 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305569 tANI_S32 global_operating_class = 0;
5570 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305571 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305572 int retVal;
5573
5574 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305575
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305576 if (!pAdapter) {
5577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5578 return -EINVAL;
5579 }
5580
Atul Mittal115287b2014-07-08 13:26:33 +05305581 ret = wlan_hdd_validate_context(pHddCtx);
5582 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305584 return -EINVAL;
5585 }
5586 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305588 return -ENOTSUPP;
5589 }
5590 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5591 data, data_len,
5592 wlan_hdd_tdls_config_get_status_policy)) {
5593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5594 return -EINVAL;
5595 }
5596
5597 /* Parse and fetch mac address */
5598 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5600 return -EINVAL;
5601 }
5602
5603 memcpy(peer, nla_data(
5604 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5605 sizeof(peer));
5606 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5607
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305608 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305609
Atul Mittal115287b2014-07-08 13:26:33 +05305610 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305611 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305612 NLMSG_HDRLEN);
5613
5614 if (!skb) {
5615 hddLog(VOS_TRACE_LEVEL_ERROR,
5616 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5617 return -EINVAL;
5618 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305619 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 +05305620 reason,
5621 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305622 global_operating_class,
5623 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305624 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305625 if (nla_put_s32(skb,
5626 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5627 state) ||
5628 nla_put_s32(skb,
5629 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5630 reason) ||
5631 nla_put_s32(skb,
5632 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5633 global_operating_class) ||
5634 nla_put_s32(skb,
5635 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5636 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305637
5638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5639 goto nla_put_failure;
5640 }
5641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305642 retVal = cfg80211_vendor_cmd_reply(skb);
5643 EXIT();
5644 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305645
5646nla_put_failure:
5647 kfree_skb(skb);
5648 return -EINVAL;
5649}
5650
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305651static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5652 struct wireless_dev *wdev,
5653 const void *data,
5654 int data_len)
5655{
5656 int ret = 0;
5657
5658 vos_ssr_protect(__func__);
5659 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5660 vos_ssr_unprotect(__func__);
5661
5662 return ret;
5663}
5664
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305665static int wlan_hdd_cfg80211_exttdls_callback(
5666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5667 const tANI_U8* mac,
5668#else
5669 tANI_U8* mac,
5670#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305671 tANI_S32 state,
5672 tANI_S32 reason,
5673 void *ctx)
5674{
5675 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305676 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305677 tANI_S32 global_operating_class = 0;
5678 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305679 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305680
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305681 ENTER();
5682
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305683 if (!pAdapter) {
5684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5685 return -EINVAL;
5686 }
5687
5688 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305689 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305691 return -EINVAL;
5692 }
5693
5694 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305696 return -ENOTSUPP;
5697 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305698 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5700 NULL,
5701#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305702 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5703 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5704 GFP_KERNEL);
5705
5706 if (!skb) {
5707 hddLog(VOS_TRACE_LEVEL_ERROR,
5708 FL("cfg80211_vendor_event_alloc failed"));
5709 return -EINVAL;
5710 }
5711 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305712 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5713 reason,
5714 state,
5715 global_operating_class,
5716 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305717 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5718 MAC_ADDR_ARRAY(mac));
5719
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305720 if (nla_put(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5722 VOS_MAC_ADDR_SIZE, mac) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5725 state) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5728 reason) ||
5729 nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5731 channel) ||
5732 nla_put_s32(skb,
5733 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5734 global_operating_class)
5735 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305736 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5737 goto nla_put_failure;
5738 }
5739
5740 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305741 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305742 return (0);
5743
5744nla_put_failure:
5745 kfree_skb(skb);
5746 return -EINVAL;
5747}
5748
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305749static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305750 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305751 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305752 int data_len)
5753{
5754 u8 peer[6] = {0};
5755 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305756 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5757 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5758 eHalStatus status;
5759 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305760 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305761 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305762
5763 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305764
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305765 if (!dev) {
5766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5767 return -EINVAL;
5768 }
5769
5770 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5771 if (!pAdapter) {
5772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5773 return -EINVAL;
5774 }
5775
Atul Mittal115287b2014-07-08 13:26:33 +05305776 status = wlan_hdd_validate_context(pHddCtx);
5777 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305779 return -EINVAL;
5780 }
5781 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305783 return -ENOTSUPP;
5784 }
5785 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5786 data, data_len,
5787 wlan_hdd_tdls_config_enable_policy)) {
5788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5789 return -EINVAL;
5790 }
5791
5792 /* Parse and fetch mac address */
5793 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5795 return -EINVAL;
5796 }
5797
5798 memcpy(peer, nla_data(
5799 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5800 sizeof(peer));
5801 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5802
5803 /* Parse and fetch channel */
5804 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5806 return -EINVAL;
5807 }
5808 pReqMsg.channel = nla_get_s32(
5809 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5810 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5811
5812 /* Parse and fetch global operating class */
5813 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5814 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5815 return -EINVAL;
5816 }
5817 pReqMsg.global_operating_class = nla_get_s32(
5818 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5820 pReqMsg.global_operating_class);
5821
5822 /* Parse and fetch latency ms */
5823 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5824 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5825 return -EINVAL;
5826 }
5827 pReqMsg.max_latency_ms = nla_get_s32(
5828 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5829 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5830 pReqMsg.max_latency_ms);
5831
5832 /* Parse and fetch required bandwidth kbps */
5833 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5835 return -EINVAL;
5836 }
5837
5838 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5839 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5840 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5841 pReqMsg.min_bandwidth_kbps);
5842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305843 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305844 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305845 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305846 wlan_hdd_cfg80211_exttdls_callback);
5847
5848 EXIT();
5849 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305850}
5851
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305852static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5853 struct wireless_dev *wdev,
5854 const void *data,
5855 int data_len)
5856{
5857 int ret = 0;
5858
5859 vos_ssr_protect(__func__);
5860 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5861 vos_ssr_unprotect(__func__);
5862
5863 return ret;
5864}
5865
5866static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305867 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305868 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305869 int data_len)
5870{
5871 u8 peer[6] = {0};
5872 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305873 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5874 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5875 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305876 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305877 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305878
5879 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305880
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305881 if (!dev) {
5882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5883 return -EINVAL;
5884 }
5885
5886 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5887 if (!pAdapter) {
5888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5889 return -EINVAL;
5890 }
5891
Atul Mittal115287b2014-07-08 13:26:33 +05305892 status = wlan_hdd_validate_context(pHddCtx);
5893 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305895 return -EINVAL;
5896 }
5897 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305898 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305899 return -ENOTSUPP;
5900 }
5901 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5902 data, data_len,
5903 wlan_hdd_tdls_config_disable_policy)) {
5904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5905 return -EINVAL;
5906 }
5907 /* Parse and fetch mac address */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5910 return -EINVAL;
5911 }
5912
5913 memcpy(peer, nla_data(
5914 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5915 sizeof(peer));
5916 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305918 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5919
5920 EXIT();
5921 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305922}
5923
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305924static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5925 struct wireless_dev *wdev,
5926 const void *data,
5927 int data_len)
5928{
5929 int ret = 0;
5930
5931 vos_ssr_protect(__func__);
5932 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5933 vos_ssr_unprotect(__func__);
5934
5935 return ret;
5936}
5937
Dasari Srinivas7875a302014-09-26 17:50:57 +05305938static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305939__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305940 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305941 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305942{
5943 struct net_device *dev = wdev->netdev;
5944 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5945 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5946 struct sk_buff *skb = NULL;
5947 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305948 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305949
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305950 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305951
5952 ret = wlan_hdd_validate_context(pHddCtx);
5953 if (0 != ret)
5954 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305955 return ret;
5956 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305957 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5958 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5959 fset |= WIFI_FEATURE_INFRA;
5960 }
5961
5962 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5963 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5964 fset |= WIFI_FEATURE_INFRA_5G;
5965 }
5966
5967#ifdef WLAN_FEATURE_P2P
5968 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5969 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5970 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5971 fset |= WIFI_FEATURE_P2P;
5972 }
5973#endif
5974
5975 /* Soft-AP is supported currently by default */
5976 fset |= WIFI_FEATURE_SOFT_AP;
5977
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305978 /* HOTSPOT is a supplicant feature, enable it by default */
5979 fset |= WIFI_FEATURE_HOTSPOT;
5980
Dasari Srinivas7875a302014-09-26 17:50:57 +05305981#ifdef WLAN_FEATURE_EXTSCAN
5982 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305983 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5984 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5985 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305986 fset |= WIFI_FEATURE_EXTSCAN;
5987 }
5988#endif
5989
Dasari Srinivas7875a302014-09-26 17:50:57 +05305990 if (sme_IsFeatureSupportedByFW(NAN)) {
5991 hddLog(LOG1, FL("NAN is supported by firmware"));
5992 fset |= WIFI_FEATURE_NAN;
5993 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305994
5995 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305996 if (sme_IsFeatureSupportedByFW(RTT) &&
5997 pHddCtx->cfg_ini->enable_rtt_support) {
5998 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305999 fset |= WIFI_FEATURE_D2AP_RTT;
6000 }
6001
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306002 if (sme_IsFeatureSupportedByFW(RTT3)) {
6003 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6004 fset |= WIFI_FEATURE_RTT3;
6005 }
6006
Dasari Srinivas7875a302014-09-26 17:50:57 +05306007#ifdef FEATURE_WLAN_BATCH_SCAN
6008 if (fset & WIFI_FEATURE_EXTSCAN) {
6009 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6010 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6011 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6012 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6013 fset |= WIFI_FEATURE_BATCH_SCAN;
6014 }
6015#endif
6016
6017#ifdef FEATURE_WLAN_SCAN_PNO
6018 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6019 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6020 hddLog(LOG1, FL("PNO is supported by firmware"));
6021 fset |= WIFI_FEATURE_PNO;
6022 }
6023#endif
6024
6025 /* STA+STA is supported currently by default */
6026 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6027
6028#ifdef FEATURE_WLAN_TDLS
6029 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6030 sme_IsFeatureSupportedByFW(TDLS)) {
6031 hddLog(LOG1, FL("TDLS is supported by firmware"));
6032 fset |= WIFI_FEATURE_TDLS;
6033 }
6034
6035 /* TDLS_OFFCHANNEL is not supported currently by default */
6036#endif
6037
6038#ifdef WLAN_AP_STA_CONCURRENCY
6039 /* AP+STA concurrency is supported currently by default */
6040 fset |= WIFI_FEATURE_AP_STA;
6041#endif
6042
Mukul Sharma5add0532015-08-17 15:57:47 +05306043#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306044 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6045 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306046 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6047 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306048 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306049#endif
6050
Dasari Srinivas7875a302014-09-26 17:50:57 +05306051 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6052 NLMSG_HDRLEN);
6053
6054 if (!skb) {
6055 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6056 return -EINVAL;
6057 }
6058 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6059
6060 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6061 hddLog(LOGE, FL("nla put fail"));
6062 goto nla_put_failure;
6063 }
6064
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306065 ret = cfg80211_vendor_cmd_reply(skb);
6066 EXIT();
6067 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306068
6069nla_put_failure:
6070 kfree_skb(skb);
6071 return -EINVAL;
6072}
6073
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306074static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306075wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6076 struct wireless_dev *wdev,
6077 const void *data, int data_len)
6078{
6079 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306080 vos_ssr_protect(__func__);
6081 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6082 vos_ssr_unprotect(__func__);
6083
6084 return ret;
6085}
6086
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306087
6088static const struct
6089nla_policy
6090qca_wlan_vendor_wifi_logger_get_ring_data_policy
6091[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6092 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6093 = {.type = NLA_U32 },
6094};
6095
6096static int
6097 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6098 struct wireless_dev *wdev,
6099 const void *data,
6100 int data_len)
6101{
6102 int ret;
6103 VOS_STATUS status;
6104 uint32_t ring_id;
6105 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6106 struct nlattr *tb
6107 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6108
6109 ENTER();
6110
6111 ret = wlan_hdd_validate_context(hdd_ctx);
6112 if (0 != ret) {
6113 return ret;
6114 }
6115
6116 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6117 data, data_len,
6118 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6119 hddLog(LOGE, FL("Invalid attribute"));
6120 return -EINVAL;
6121 }
6122
6123 /* Parse and fetch ring id */
6124 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6125 hddLog(LOGE, FL("attr ATTR failed"));
6126 return -EINVAL;
6127 }
6128
6129 ring_id = nla_get_u32(
6130 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6131
6132 hddLog(LOG1, FL("Bug report triggered by framework"));
6133
6134 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6135 WLAN_LOG_INDICATOR_FRAMEWORK,
6136 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306137 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306138 );
6139 if (VOS_STATUS_SUCCESS != status) {
6140 hddLog(LOGE, FL("Failed to trigger bug report"));
6141
6142 return -EINVAL;
6143 }
6144
6145 return 0;
6146
6147
6148}
6149
6150
6151static int
6152 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6153 struct wireless_dev *wdev,
6154 const void *data,
6155 int data_len)
6156{
6157 int ret = 0;
6158
6159 vos_ssr_protect(__func__);
6160 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6161 wdev, data, data_len);
6162 vos_ssr_unprotect(__func__);
6163
6164 return ret;
6165
6166}
6167
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306168#define MAX_CONCURRENT_MATRIX \
6169 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6170#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6171 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6172static const struct nla_policy
6173wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6174 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6175};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306176
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306177static int
6178__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306179 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306180 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306181{
6182 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6183 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306184 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306185 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306186 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6187 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306188
6189 ENTER();
6190
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306191 ret = wlan_hdd_validate_context(pHddCtx);
6192 if (0 != ret)
6193 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306194 return ret;
6195 }
6196
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306197 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6198 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306199 hddLog(LOGE, FL("Invalid ATTR"));
6200 return -EINVAL;
6201 }
6202
6203 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306204 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306205 hddLog(LOGE, FL("Attr max feature set size failed"));
6206 return -EINVAL;
6207 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306208 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306209 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6210
6211 /* Fill feature combination matrix */
6212 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306213 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6214 WIFI_FEATURE_P2P;
6215
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306216 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6217 WIFI_FEATURE_SOFT_AP;
6218
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306219 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6220 WIFI_FEATURE_SOFT_AP;
6221
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306222 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6223 WIFI_FEATURE_SOFT_AP |
6224 WIFI_FEATURE_P2P;
6225
6226 /* Add more feature combinations here */
6227
6228 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6229 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6230 hddLog(LOG1, "Feature set matrix");
6231 for (i = 0; i < feature_sets; i++)
6232 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6233
6234 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6235 sizeof(u32) * feature_sets +
6236 NLMSG_HDRLEN);
6237
6238 if (reply_skb) {
6239 if (nla_put_u32(reply_skb,
6240 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6241 feature_sets) ||
6242 nla_put(reply_skb,
6243 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6244 sizeof(u32) * feature_sets, feature_set_matrix)) {
6245 hddLog(LOGE, FL("nla put fail"));
6246 kfree_skb(reply_skb);
6247 return -EINVAL;
6248 }
6249
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306250 ret = cfg80211_vendor_cmd_reply(reply_skb);
6251 EXIT();
6252 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306253 }
6254 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6255 return -ENOMEM;
6256
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306257}
6258
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306259#undef MAX_CONCURRENT_MATRIX
6260#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6261
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306262static int
6263wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6264 struct wireless_dev *wdev,
6265 const void *data, int data_len)
6266{
6267 int ret = 0;
6268
6269 vos_ssr_protect(__func__);
6270 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6271 data_len);
6272 vos_ssr_unprotect(__func__);
6273
6274 return ret;
6275}
6276
c_manjeecfd1efb2015-09-25 19:32:34 +05306277
6278static int
6279__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6280 struct wireless_dev *wdev,
6281 const void *data, int data_len)
6282{
6283 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6284 int ret;
6285 ENTER();
6286
6287 ret = wlan_hdd_validate_context(pHddCtx);
6288 if (0 != ret)
6289 {
6290 return ret;
6291 }
6292
6293 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6294 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6295 {
6296 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306297 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306298 }
6299 /*call common API for FW mem dump req*/
6300 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6301
Abhishek Singhc783fa72015-12-09 18:07:34 +05306302 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306303 {
6304 /*indicate to userspace the status of fw mem dump */
6305 wlan_indicate_mem_dump_complete(true);
6306 }
6307 else
6308 {
6309 /*else send failure to userspace */
6310 wlan_indicate_mem_dump_complete(false);
6311 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306312 EXIT();
6313 return ret;
6314}
6315
6316/**
6317 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6318 * @wiphy: pointer to wireless wiphy structure.
6319 * @wdev: pointer to wireless_dev structure.
6320 * @data: Pointer to the NL data.
6321 * @data_len:Length of @data
6322 *
6323 * This is called when wlan driver needs to get the firmware memory dump
6324 * via vendor specific command.
6325 *
6326 * Return: 0 on success, error number otherwise.
6327 */
6328
6329static int
6330wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6331 struct wireless_dev *wdev,
6332 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306333{
6334 int ret = 0;
6335 vos_ssr_protect(__func__);
6336 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6337 data_len);
6338 vos_ssr_unprotect(__func__);
6339 return ret;
6340}
c_manjeecfd1efb2015-09-25 19:32:34 +05306341
Sushant Kaushik8e644982015-09-23 12:18:54 +05306342static const struct
6343nla_policy
6344qca_wlan_vendor_wifi_logger_start_policy
6345[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6346 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6347 = {.type = NLA_U32 },
6348 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6349 = {.type = NLA_U32 },
6350 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6351 = {.type = NLA_U32 },
6352};
6353
6354/**
6355 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6356 * or disable the collection of packet statistics from the firmware
6357 * @wiphy: WIPHY structure pointer
6358 * @wdev: Wireless device structure pointer
6359 * @data: Pointer to the data received
6360 * @data_len: Length of the data received
6361 *
6362 * This function is used to enable or disable the collection of packet
6363 * statistics from the firmware
6364 *
6365 * Return: 0 on success and errno on failure
6366 */
6367static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6368 struct wireless_dev *wdev,
6369 const void *data,
6370 int data_len)
6371{
6372 eHalStatus status;
6373 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6374 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6375 tAniWifiStartLog start_log;
6376
6377 status = wlan_hdd_validate_context(hdd_ctx);
6378 if (0 != status) {
6379 return -EINVAL;
6380 }
6381
6382 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6383 data, data_len,
6384 qca_wlan_vendor_wifi_logger_start_policy)) {
6385 hddLog(LOGE, FL("Invalid attribute"));
6386 return -EINVAL;
6387 }
6388
6389 /* Parse and fetch ring id */
6390 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6391 hddLog(LOGE, FL("attr ATTR failed"));
6392 return -EINVAL;
6393 }
6394 start_log.ringId = nla_get_u32(
6395 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6396 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6397
6398 /* Parse and fetch verbose level */
6399 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6400 hddLog(LOGE, FL("attr verbose_level failed"));
6401 return -EINVAL;
6402 }
6403 start_log.verboseLevel = nla_get_u32(
6404 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6405 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6406
6407 /* Parse and fetch flag */
6408 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6409 hddLog(LOGE, FL("attr flag failed"));
6410 return -EINVAL;
6411 }
6412 start_log.flag = nla_get_u32(
6413 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6414 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6415
6416 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306417 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6418 !vos_isPktStatsEnabled()))
6419
Sushant Kaushik8e644982015-09-23 12:18:54 +05306420 {
6421 hddLog(LOGE, FL("per pkt stats not enabled"));
6422 return -EINVAL;
6423 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306424
Sushant Kaushik33200572015-08-05 16:46:20 +05306425 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306426 return 0;
6427}
6428
6429/**
6430 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6431 * or disable the collection of packet statistics from the firmware
6432 * @wiphy: WIPHY structure pointer
6433 * @wdev: Wireless device structure pointer
6434 * @data: Pointer to the data received
6435 * @data_len: Length of the data received
6436 *
6437 * This function is used to enable or disable the collection of packet
6438 * statistics from the firmware
6439 *
6440 * Return: 0 on success and errno on failure
6441 */
6442static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6443 struct wireless_dev *wdev,
6444 const void *data,
6445 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306446{
6447 int ret = 0;
6448
6449 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306450
6451 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6452 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306453 vos_ssr_unprotect(__func__);
6454
6455 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306456}
6457
6458
Agarwal Ashish738843c2014-09-25 12:27:56 +05306459static const struct nla_policy
6460wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6461 +1] =
6462{
6463 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6464};
6465
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306466static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306467 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306468 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306469 int data_len)
6470{
6471 struct net_device *dev = wdev->netdev;
6472 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6473 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6474 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6475 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6476 eHalStatus status;
6477 u32 dfsFlag = 0;
6478
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306479 ENTER();
6480
Agarwal Ashish738843c2014-09-25 12:27:56 +05306481 status = wlan_hdd_validate_context(pHddCtx);
6482 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306483 return -EINVAL;
6484 }
6485 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6486 data, data_len,
6487 wlan_hdd_set_no_dfs_flag_config_policy)) {
6488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6489 return -EINVAL;
6490 }
6491
6492 /* Parse and fetch required bandwidth kbps */
6493 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6495 return -EINVAL;
6496 }
6497
6498 dfsFlag = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6500 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6501 dfsFlag);
6502
6503 pHddCtx->disable_dfs_flag = dfsFlag;
6504
6505 sme_disable_dfs_channel(hHal, dfsFlag);
6506 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306507
6508 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306509 return 0;
6510}
Atul Mittal115287b2014-07-08 13:26:33 +05306511
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306512static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6513 struct wireless_dev *wdev,
6514 const void *data,
6515 int data_len)
6516{
6517 int ret = 0;
6518
6519 vos_ssr_protect(__func__);
6520 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6521 vos_ssr_unprotect(__func__);
6522
6523 return ret;
6524
6525}
6526
Mukul Sharma2a271632014-10-13 14:59:01 +05306527const struct
6528nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6529{
6530 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306531 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6532 .type = NLA_UNSPEC,
6533 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306534};
6535
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306536static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306537 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306538{
6539
6540 u8 bssid[6] = {0};
6541 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6542 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6543 eHalStatus status = eHAL_STATUS_SUCCESS;
6544 v_U32_t isFwrRoamEnabled = FALSE;
6545 int ret;
6546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306547 ENTER();
6548
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306549 ret = wlan_hdd_validate_context(pHddCtx);
6550 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306551 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306552 }
6553
6554 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6555 data, data_len,
6556 qca_wlan_vendor_attr);
6557 if (ret){
6558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6559 return -EINVAL;
6560 }
6561
6562 /* Parse and fetch Enable flag */
6563 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6565 return -EINVAL;
6566 }
6567
6568 isFwrRoamEnabled = nla_get_u32(
6569 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6570
6571 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6572
6573 /* Parse and fetch bssid */
6574 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6576 return -EINVAL;
6577 }
6578
6579 memcpy(bssid, nla_data(
6580 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6581 sizeof(bssid));
6582 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6583
6584 //Update roaming
6585 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306586 if (!HAL_STATUS_SUCCESS(status)) {
6587 hddLog(LOGE,
6588 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6589 return -EINVAL;
6590 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306591 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306592 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306593}
6594
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306595static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6596 struct wireless_dev *wdev, const void *data, int data_len)
6597{
6598 int ret = 0;
6599
6600 vos_ssr_protect(__func__);
6601 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6602 vos_ssr_unprotect(__func__);
6603
6604 return ret;
6605}
6606
Sushant Kaushik847890c2015-09-28 16:05:17 +05306607static const struct
6608nla_policy
6609qca_wlan_vendor_get_wifi_info_policy[
6610 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6611 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6612 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6613};
6614
6615
6616/**
6617 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6618 * @wiphy: pointer to wireless wiphy structure.
6619 * @wdev: pointer to wireless_dev structure.
6620 * @data: Pointer to the data to be passed via vendor interface
6621 * @data_len:Length of the data to be passed
6622 *
6623 * This is called when wlan driver needs to send wifi driver related info
6624 * (driver/fw version) to the user space application upon request.
6625 *
6626 * Return: Return the Success or Failure code.
6627 */
6628static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6629 struct wireless_dev *wdev,
6630 const void *data, int data_len)
6631{
6632 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6633 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6634 tSirVersionString version;
6635 uint32 version_len;
6636 uint8 attr;
6637 int status;
6638 struct sk_buff *reply_skb = NULL;
6639
6640 if (VOS_FTM_MODE == hdd_get_conparam()) {
6641 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6642 return -EINVAL;
6643 }
6644
6645 status = wlan_hdd_validate_context(hdd_ctx);
6646 if (0 != status) {
6647 hddLog(LOGE, FL("HDD context is not valid"));
6648 return -EINVAL;
6649 }
6650
6651 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6652 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6653 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6654 return -EINVAL;
6655 }
6656
6657 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6658 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6659 QWLAN_VERSIONSTR);
6660 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6661 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6662 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6663 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6664 hdd_ctx->fw_Version);
6665 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6666 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6667 } else {
6668 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6669 return -EINVAL;
6670 }
6671
6672 version_len = strlen(version);
6673 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6674 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6675 if (!reply_skb) {
6676 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6677 return -ENOMEM;
6678 }
6679
6680 if (nla_put(reply_skb, attr, version_len, version)) {
6681 hddLog(LOGE, FL("nla put fail"));
6682 kfree_skb(reply_skb);
6683 return -EINVAL;
6684 }
6685
6686 return cfg80211_vendor_cmd_reply(reply_skb);
6687}
6688
6689/**
6690 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6691 * @wiphy: pointer to wireless wiphy structure.
6692 * @wdev: pointer to wireless_dev structure.
6693 * @data: Pointer to the data to be passed via vendor interface
6694 * @data_len:Length of the data to be passed
6695 * @data_len: Length of the data received
6696 *
6697 * This function is used to enable or disable the collection of packet
6698 * statistics from the firmware
6699 *
6700 * Return: 0 on success and errno on failure
6701 */
6702
6703static int
6704wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6705 struct wireless_dev *wdev,
6706 const void *data, int data_len)
6707
6708
6709{
6710 int ret = 0;
6711
6712 vos_ssr_protect(__func__);
6713 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6714 wdev, data, data_len);
6715 vos_ssr_unprotect(__func__);
6716
6717 return ret;
6718}
6719
6720
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306721/*
6722 * define short names for the global vendor params
6723 * used by __wlan_hdd_cfg80211_monitor_rssi()
6724 */
6725#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6726#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6727#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6728#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6729#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6730
6731/**---------------------------------------------------------------------------
6732
6733 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6734 monitor start is completed successfully.
6735
6736 \return - None
6737
6738 --------------------------------------------------------------------------*/
6739void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6740{
6741 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6742
6743 if (NULL == pHddCtx)
6744 {
6745 hddLog(VOS_TRACE_LEVEL_ERROR,
6746 "%s: HDD context is NULL",__func__);
6747 return;
6748 }
6749
6750 if (VOS_STATUS_SUCCESS == status)
6751 {
6752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6753 }
6754 else
6755 {
6756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6757 }
6758
6759 return;
6760}
6761
6762/**---------------------------------------------------------------------------
6763
6764 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6765 stop is completed successfully.
6766
6767 \return - None
6768
6769 --------------------------------------------------------------------------*/
6770void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6771{
6772 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6773
6774 if (NULL == pHddCtx)
6775 {
6776 hddLog(VOS_TRACE_LEVEL_ERROR,
6777 "%s: HDD context is NULL",__func__);
6778 return;
6779 }
6780
6781 if (VOS_STATUS_SUCCESS == status)
6782 {
6783 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6784 }
6785 else
6786 {
6787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6788 }
6789
6790 return;
6791}
6792
6793/**
6794 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6795 * @wiphy: Pointer to wireless phy
6796 * @wdev: Pointer to wireless device
6797 * @data: Pointer to data
6798 * @data_len: Data length
6799 *
6800 * Return: 0 on success, negative errno on failure
6801 */
6802
6803static int
6804__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6805 struct wireless_dev *wdev,
6806 const void *data,
6807 int data_len)
6808{
6809 struct net_device *dev = wdev->netdev;
6810 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6811 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6812 hdd_station_ctx_t *pHddStaCtx;
6813 struct nlattr *tb[PARAM_MAX + 1];
6814 tpSirRssiMonitorReq pReq;
6815 eHalStatus status;
6816 int ret;
6817 uint32_t control;
6818 static const struct nla_policy policy[PARAM_MAX + 1] = {
6819 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6820 [PARAM_CONTROL] = { .type = NLA_U32 },
6821 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6822 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6823 };
6824
6825 ENTER();
6826
6827 ret = wlan_hdd_validate_context(hdd_ctx);
6828 if (0 != ret) {
6829 return -EINVAL;
6830 }
6831
6832 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6833 hddLog(LOGE, FL("Not in Connected state!"));
6834 return -ENOTSUPP;
6835 }
6836
6837 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6838 hddLog(LOGE, FL("Invalid ATTR"));
6839 return -EINVAL;
6840 }
6841
6842 if (!tb[PARAM_REQUEST_ID]) {
6843 hddLog(LOGE, FL("attr request id failed"));
6844 return -EINVAL;
6845 }
6846
6847 if (!tb[PARAM_CONTROL]) {
6848 hddLog(LOGE, FL("attr control failed"));
6849 return -EINVAL;
6850 }
6851
6852 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6853
6854 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6855 if(NULL == pReq)
6856 {
6857 hddLog(LOGE,
6858 FL("vos_mem_alloc failed "));
6859 return eHAL_STATUS_FAILED_ALLOC;
6860 }
6861 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6862
6863 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6864 pReq->sessionId = pAdapter->sessionId;
6865 pReq->rssiMonitorCbContext = hdd_ctx;
6866 control = nla_get_u32(tb[PARAM_CONTROL]);
6867 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6868
6869 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6870 pReq->requestId, pReq->sessionId, control);
6871
6872 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6873 if (!tb[PARAM_MIN_RSSI]) {
6874 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306875 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306876 }
6877
6878 if (!tb[PARAM_MAX_RSSI]) {
6879 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306880 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306881 }
6882
6883 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6884 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6885 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6886
6887 if (!(pReq->minRssi < pReq->maxRssi)) {
6888 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6889 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306890 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306891 }
6892 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6893 pReq->minRssi, pReq->maxRssi);
6894 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6895
6896 }
6897 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6898 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6899 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6900 }
6901 else {
6902 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306903 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306904 }
6905
6906 if (!HAL_STATUS_SUCCESS(status)) {
6907 hddLog(LOGE,
6908 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306909 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306910 }
6911
6912 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306913fail:
6914 vos_mem_free(pReq);
6915 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306916}
6917
6918/*
6919 * done with short names for the global vendor params
6920 * used by __wlan_hdd_cfg80211_monitor_rssi()
6921 */
6922#undef PARAM_MAX
6923#undef PARAM_CONTROL
6924#undef PARAM_REQUEST_ID
6925#undef PARAM_MAX_RSSI
6926#undef PARAM_MIN_RSSI
6927
6928/**
6929 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6930 * @wiphy: wiphy structure pointer
6931 * @wdev: Wireless device structure pointer
6932 * @data: Pointer to the data received
6933 * @data_len: Length of @data
6934 *
6935 * Return: 0 on success; errno on failure
6936 */
6937static int
6938wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6939 const void *data, int data_len)
6940{
6941 int ret;
6942
6943 vos_ssr_protect(__func__);
6944 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6945 vos_ssr_unprotect(__func__);
6946
6947 return ret;
6948}
6949
6950/**
6951 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6952 * @hddctx: HDD context
6953 * @data: rssi breached event data
6954 *
6955 * This function reads the rssi breached event %data and fill in the skb with
6956 * NL attributes and send up the NL event.
6957 * This callback execute in atomic context and must not invoke any
6958 * blocking calls.
6959 *
6960 * Return: none
6961 */
6962void hdd_rssi_threshold_breached_cb(void *hddctx,
6963 struct rssi_breach_event *data)
6964{
6965 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6966 int status;
6967 struct sk_buff *skb;
6968
6969 ENTER();
6970 status = wlan_hdd_validate_context(pHddCtx);
6971
6972 if (0 != status) {
6973 return;
6974 }
6975
6976 if (!data) {
6977 hddLog(LOGE, FL("data is null"));
6978 return;
6979 }
6980
6981 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6982#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6983 NULL,
6984#endif
6985 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6986 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6987 GFP_KERNEL);
6988
6989 if (!skb) {
6990 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6991 return;
6992 }
6993
6994 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6995 data->request_id, data->curr_rssi);
6996 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6997 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6998
6999 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7000 data->request_id) ||
7001 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7002 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7003 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7004 data->curr_rssi)) {
7005 hddLog(LOGE, FL("nla put fail"));
7006 goto fail;
7007 }
7008
7009 cfg80211_vendor_event(skb, GFP_KERNEL);
7010 return;
7011
7012fail:
7013 kfree_skb(skb);
7014 return;
7015}
7016
7017
7018
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307019/**
7020 * __wlan_hdd_cfg80211_setband() - set band
7021 * @wiphy: Pointer to wireless phy
7022 * @wdev: Pointer to wireless device
7023 * @data: Pointer to data
7024 * @data_len: Data length
7025 *
7026 * Return: 0 on success, negative errno on failure
7027 */
7028static int
7029__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7030 struct wireless_dev *wdev,
7031 const void *data,
7032 int data_len)
7033{
7034 struct net_device *dev = wdev->netdev;
7035 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7036 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7037 int ret;
7038 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7039 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7040
7041 ENTER();
7042
7043 ret = wlan_hdd_validate_context(hdd_ctx);
7044 if (0 != ret) {
7045 hddLog(LOGE, FL("HDD context is not valid"));
7046 return ret;
7047 }
7048
7049 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7050 policy)) {
7051 hddLog(LOGE, FL("Invalid ATTR"));
7052 return -EINVAL;
7053 }
7054
7055 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7056 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7057 return -EINVAL;
7058 }
7059
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307060 hdd_ctx->isSetBandByNL = TRUE;
7061 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307062 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307063 hdd_ctx->isSetBandByNL = FALSE;
7064
7065 EXIT();
7066 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307067}
7068
7069/**
7070 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7071 * @wiphy: wiphy structure pointer
7072 * @wdev: Wireless device structure pointer
7073 * @data: Pointer to the data received
7074 * @data_len: Length of @data
7075 *
7076 * Return: 0 on success; errno on failure
7077 */
7078static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7079 struct wireless_dev *wdev,
7080 const void *data,
7081 int data_len)
7082{
7083 int ret = 0;
7084
7085 vos_ssr_protect(__func__);
7086 ret = __wlan_hdd_cfg80211_setband(wiphy,
7087 wdev, data, data_len);
7088 vos_ssr_unprotect(__func__);
7089
7090 return ret;
7091}
7092
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307093#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7094/**
7095 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7096 * @hdd_ctx: HDD context
7097 * @request_id: [input] request id
7098 * @pattern_id: [output] pattern id
7099 *
7100 * This function loops through request id to pattern id array
7101 * if the slot is available, store the request id and return pattern id
7102 * if entry exists, return the pattern id
7103 *
7104 * Return: 0 on success and errno on failure
7105 */
7106static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7107 uint32_t request_id,
7108 uint8_t *pattern_id)
7109{
7110 uint32_t i;
7111
7112 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7113 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7114 {
7115 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7116 {
7117 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7118 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7119 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7120 return 0;
7121 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7122 request_id) {
7123 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7124 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7125 return 0;
7126 }
7127 }
7128 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7129 return -EINVAL;
7130}
7131
7132/**
7133 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7134 * @hdd_ctx: HDD context
7135 * @request_id: [input] request id
7136 * @pattern_id: [output] pattern id
7137 *
7138 * This function loops through request id to pattern id array
7139 * reset request id to 0 (slot available again) and
7140 * return pattern id
7141 *
7142 * Return: 0 on success and errno on failure
7143 */
7144static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7145 uint32_t request_id,
7146 uint8_t *pattern_id)
7147{
7148 uint32_t i;
7149
7150 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7151 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7152 {
7153 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7154 {
7155 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7156 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7157 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7158 return 0;
7159 }
7160 }
7161 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7162 return -EINVAL;
7163}
7164
7165
7166/*
7167 * define short names for the global vendor params
7168 * used by __wlan_hdd_cfg80211_offloaded_packets()
7169 */
7170#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7171#define PARAM_REQUEST_ID \
7172 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7173#define PARAM_CONTROL \
7174 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7175#define PARAM_IP_PACKET \
7176 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7177#define PARAM_SRC_MAC_ADDR \
7178 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7179#define PARAM_DST_MAC_ADDR \
7180 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7181#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7182
7183/**
7184 * wlan_hdd_add_tx_ptrn() - add tx pattern
7185 * @adapter: adapter pointer
7186 * @hdd_ctx: hdd context
7187 * @tb: nl attributes
7188 *
7189 * This function reads the NL attributes and forms a AddTxPtrn message
7190 * posts it to SME.
7191 *
7192 */
7193static int
7194wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7195 struct nlattr **tb)
7196{
7197 struct sSirAddPeriodicTxPtrn *add_req;
7198 eHalStatus status;
7199 uint32_t request_id, ret, len;
7200 uint8_t pattern_id = 0;
7201 v_MACADDR_t dst_addr;
7202 uint16_t eth_type = htons(ETH_P_IP);
7203
7204 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7205 {
7206 hddLog(LOGE, FL("Not in Connected state!"));
7207 return -ENOTSUPP;
7208 }
7209
7210 add_req = vos_mem_malloc(sizeof(*add_req));
7211 if (!add_req)
7212 {
7213 hddLog(LOGE, FL("memory allocation failed"));
7214 return -ENOMEM;
7215 }
7216
7217 /* Parse and fetch request Id */
7218 if (!tb[PARAM_REQUEST_ID])
7219 {
7220 hddLog(LOGE, FL("attr request id failed"));
7221 goto fail;
7222 }
7223
7224 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7225 hddLog(LOG1, FL("Request Id: %u"), request_id);
7226 if (request_id == 0)
7227 {
7228 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307229 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307230 }
7231
7232 if (!tb[PARAM_PERIOD])
7233 {
7234 hddLog(LOGE, FL("attr period failed"));
7235 goto fail;
7236 }
7237 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7238 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7239 if (add_req->usPtrnIntervalMs == 0)
7240 {
7241 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7242 goto fail;
7243 }
7244
7245 if (!tb[PARAM_SRC_MAC_ADDR])
7246 {
7247 hddLog(LOGE, FL("attr source mac address failed"));
7248 goto fail;
7249 }
7250 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7251 VOS_MAC_ADDR_SIZE);
7252 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7253 MAC_ADDR_ARRAY(add_req->macAddress));
7254
7255 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7256 VOS_MAC_ADDR_SIZE))
7257 {
7258 hddLog(LOGE,
7259 FL("input src mac address and connected ap bssid are different"));
7260 goto fail;
7261 }
7262
7263 if (!tb[PARAM_DST_MAC_ADDR])
7264 {
7265 hddLog(LOGE, FL("attr dst mac address failed"));
7266 goto fail;
7267 }
7268 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7269 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7270 MAC_ADDR_ARRAY(dst_addr.bytes));
7271
7272 if (!tb[PARAM_IP_PACKET])
7273 {
7274 hddLog(LOGE, FL("attr ip packet failed"));
7275 goto fail;
7276 }
7277 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7278 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7279
7280 if (add_req->ucPtrnSize < 0 ||
7281 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7282 HDD_ETH_HEADER_LEN))
7283 {
7284 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7285 add_req->ucPtrnSize);
7286 goto fail;
7287 }
7288
7289 len = 0;
7290 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7291 len += VOS_MAC_ADDR_SIZE;
7292 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7293 VOS_MAC_ADDR_SIZE);
7294 len += VOS_MAC_ADDR_SIZE;
7295 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7296 len += 2;
7297
7298 /*
7299 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7300 * ------------------------------------------------------------
7301 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7302 * ------------------------------------------------------------
7303 */
7304 vos_mem_copy(&add_req->ucPattern[len],
7305 nla_data(tb[PARAM_IP_PACKET]),
7306 add_req->ucPtrnSize);
7307 add_req->ucPtrnSize += len;
7308
7309 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7310 add_req->ucPattern, add_req->ucPtrnSize);
7311
7312 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7313 if (ret)
7314 {
7315 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7316 goto fail;
7317 }
7318 add_req->ucPtrnId = pattern_id;
7319 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7320
7321 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7322 if (!HAL_STATUS_SUCCESS(status))
7323 {
7324 hddLog(LOGE,
7325 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7326 goto fail;
7327 }
7328
7329 EXIT();
7330 vos_mem_free(add_req);
7331 return 0;
7332
7333fail:
7334 vos_mem_free(add_req);
7335 return -EINVAL;
7336}
7337
7338/**
7339 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7340 * @adapter: adapter pointer
7341 * @hdd_ctx: hdd context
7342 * @tb: nl attributes
7343 *
7344 * This function reads the NL attributes and forms a DelTxPtrn message
7345 * posts it to SME.
7346 *
7347 */
7348static int
7349wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7350 struct nlattr **tb)
7351{
7352 struct sSirDelPeriodicTxPtrn *del_req;
7353 eHalStatus status;
7354 uint32_t request_id, ret;
7355 uint8_t pattern_id = 0;
7356
7357 /* Parse and fetch request Id */
7358 if (!tb[PARAM_REQUEST_ID])
7359 {
7360 hddLog(LOGE, FL("attr request id failed"));
7361 return -EINVAL;
7362 }
7363 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7364 if (request_id == 0)
7365 {
7366 hddLog(LOGE, FL("request_id cannot be zero"));
7367 return -EINVAL;
7368 }
7369
7370 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7371 if (ret)
7372 {
7373 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7374 return -EINVAL;
7375 }
7376
7377 del_req = vos_mem_malloc(sizeof(*del_req));
7378 if (!del_req)
7379 {
7380 hddLog(LOGE, FL("memory allocation failed"));
7381 return -ENOMEM;
7382 }
7383
7384 vos_mem_set(del_req, sizeof(*del_req), 0);
7385 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7386 VOS_MAC_ADDR_SIZE);
7387 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7388 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7389 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7390 request_id, pattern_id, del_req->ucPatternIdBitmap);
7391
7392 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7393 if (!HAL_STATUS_SUCCESS(status))
7394 {
7395 hddLog(LOGE,
7396 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7397 goto fail;
7398 }
7399
7400 EXIT();
7401 vos_mem_free(del_req);
7402 return 0;
7403
7404fail:
7405 vos_mem_free(del_req);
7406 return -EINVAL;
7407}
7408
7409
7410/**
7411 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7412 * @wiphy: Pointer to wireless phy
7413 * @wdev: Pointer to wireless device
7414 * @data: Pointer to data
7415 * @data_len: Data length
7416 *
7417 * Return: 0 on success, negative errno on failure
7418 */
7419static int
7420__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7421 struct wireless_dev *wdev,
7422 const void *data,
7423 int data_len)
7424{
7425 struct net_device *dev = wdev->netdev;
7426 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7427 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7428 struct nlattr *tb[PARAM_MAX + 1];
7429 uint8_t control;
7430 int ret;
7431 static const struct nla_policy policy[PARAM_MAX + 1] =
7432 {
7433 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7434 [PARAM_CONTROL] = { .type = NLA_U32 },
7435 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7436 .len = VOS_MAC_ADDR_SIZE },
7437 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7438 .len = VOS_MAC_ADDR_SIZE },
7439 [PARAM_PERIOD] = { .type = NLA_U32 },
7440 };
7441
7442 ENTER();
7443
7444 ret = wlan_hdd_validate_context(hdd_ctx);
7445 if (0 != ret)
7446 {
7447 hddLog(LOGE, FL("HDD context is not valid"));
7448 return ret;
7449 }
7450
7451 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7452 {
7453 hddLog(LOGE,
7454 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7455 return -ENOTSUPP;
7456 }
7457
7458 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7459 {
7460 hddLog(LOGE, FL("Invalid ATTR"));
7461 return -EINVAL;
7462 }
7463
7464 if (!tb[PARAM_CONTROL])
7465 {
7466 hddLog(LOGE, FL("attr control failed"));
7467 return -EINVAL;
7468 }
7469 control = nla_get_u32(tb[PARAM_CONTROL]);
7470 hddLog(LOG1, FL("Control: %d"), control);
7471
7472 if (control == WLAN_START_OFFLOADED_PACKETS)
7473 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7474 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7475 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7476 else
7477 {
7478 hddLog(LOGE, FL("Invalid control: %d"), control);
7479 return -EINVAL;
7480 }
7481}
7482
7483/*
7484 * done with short names for the global vendor params
7485 * used by __wlan_hdd_cfg80211_offloaded_packets()
7486 */
7487#undef PARAM_MAX
7488#undef PARAM_REQUEST_ID
7489#undef PARAM_CONTROL
7490#undef PARAM_IP_PACKET
7491#undef PARAM_SRC_MAC_ADDR
7492#undef PARAM_DST_MAC_ADDR
7493#undef PARAM_PERIOD
7494
7495/**
7496 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7497 * @wiphy: wiphy structure pointer
7498 * @wdev: Wireless device structure pointer
7499 * @data: Pointer to the data received
7500 * @data_len: Length of @data
7501 *
7502 * Return: 0 on success; errno on failure
7503 */
7504static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7505 struct wireless_dev *wdev,
7506 const void *data,
7507 int data_len)
7508{
7509 int ret = 0;
7510
7511 vos_ssr_protect(__func__);
7512 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7513 wdev, data, data_len);
7514 vos_ssr_unprotect(__func__);
7515
7516 return ret;
7517}
7518#endif
7519
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307520static const struct
7521nla_policy
7522qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307523 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7524 .type = NLA_BINARY,
7525 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307526};
7527
7528/**
7529 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7530 * get link properties like nss, rate flags and operating frequency for
7531 * the connection with the given peer.
7532 * @wiphy: WIPHY structure pointer
7533 * @wdev: Wireless device structure pointer
7534 * @data: Pointer to the data received
7535 * @data_len: Length of the data received
7536 *
7537 * This function return the above link properties on success.
7538 *
7539 * Return: 0 on success and errno on failure
7540 */
7541static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7542 struct wireless_dev *wdev,
7543 const void *data,
7544 int data_len)
7545{
7546 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7547 struct net_device *dev = wdev->netdev;
7548 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7549 hdd_station_ctx_t *hdd_sta_ctx;
7550 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7551 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7552 uint32_t sta_id;
7553 struct sk_buff *reply_skb;
7554 uint32_t rate_flags = 0;
7555 uint8_t nss;
7556 uint8_t final_rate_flags = 0;
7557 uint32_t freq;
7558 v_CONTEXT_t pVosContext = NULL;
7559 ptSapContext pSapCtx = NULL;
7560
7561 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7563 return -EINVAL;
7564 }
7565
7566 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7567 qca_wlan_vendor_attr_policy)) {
7568 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7569 return -EINVAL;
7570 }
7571
7572 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7573 hddLog(VOS_TRACE_LEVEL_ERROR,
7574 FL("Attribute peerMac not provided for mode=%d"),
7575 adapter->device_mode);
7576 return -EINVAL;
7577 }
7578
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307579 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7580 hddLog(VOS_TRACE_LEVEL_ERROR,
7581 FL("Attribute peerMac is invalid=%d"),
7582 adapter->device_mode);
7583 return -EINVAL;
7584 }
7585
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307586 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7587 sizeof(peer_mac));
7588 hddLog(VOS_TRACE_LEVEL_INFO,
7589 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7590 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7591
7592 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7593 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7594 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7595 if ((hdd_sta_ctx->conn_info.connState !=
7596 eConnectionState_Associated) ||
7597 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7598 VOS_MAC_ADDRESS_LEN)) {
7599 hddLog(VOS_TRACE_LEVEL_ERROR,
7600 FL("Not Associated to mac "MAC_ADDRESS_STR),
7601 MAC_ADDR_ARRAY(peer_mac));
7602 return -EINVAL;
7603 }
7604
7605 nss = 1; //pronto supports only one spatial stream
7606 freq = vos_chan_to_freq(
7607 hdd_sta_ctx->conn_info.operationChannel);
7608 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7609
7610 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7611 adapter->device_mode == WLAN_HDD_SOFTAP) {
7612
7613 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7614 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7615 if(pSapCtx == NULL){
7616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7617 FL("psapCtx is NULL"));
7618 return -ENOENT;
7619 }
7620
7621
7622 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7623 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7624 !vos_is_macaddr_broadcast(
7625 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7626 vos_mem_compare(
7627 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7628 peer_mac, VOS_MAC_ADDRESS_LEN))
7629 break;
7630 }
7631
7632 if (WLAN_MAX_STA_COUNT == sta_id) {
7633 hddLog(VOS_TRACE_LEVEL_ERROR,
7634 FL("No active peer with mac="MAC_ADDRESS_STR),
7635 MAC_ADDR_ARRAY(peer_mac));
7636 return -EINVAL;
7637 }
7638
7639 nss = 1; //pronto supports only one spatial stream
7640 freq = vos_chan_to_freq(
7641 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7642 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7643 } else {
7644 hddLog(VOS_TRACE_LEVEL_ERROR,
7645 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7646 MAC_ADDR_ARRAY(peer_mac));
7647 return -EINVAL;
7648 }
7649
7650 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7651 if (rate_flags & eHAL_TX_RATE_VHT80) {
7652 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307653#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7654 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307655 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307656#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307657 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7658 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307659#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7660 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307661 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307662#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307663 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7664 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7665 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7666 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307667#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7668 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307669 if (rate_flags & eHAL_TX_RATE_HT40)
7670 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307671#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307672 }
7673
7674 if (rate_flags & eHAL_TX_RATE_SGI) {
7675 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7676 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7677 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7678 }
7679 }
7680
7681 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7682 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7683
7684 if (NULL == reply_skb) {
7685 hddLog(VOS_TRACE_LEVEL_ERROR,
7686 FL("getLinkProperties: skb alloc failed"));
7687 return -EINVAL;
7688 }
7689
7690 if (nla_put_u8(reply_skb,
7691 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7692 nss) ||
7693 nla_put_u8(reply_skb,
7694 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7695 final_rate_flags) ||
7696 nla_put_u32(reply_skb,
7697 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7698 freq)) {
7699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7700 kfree_skb(reply_skb);
7701 return -EINVAL;
7702 }
7703
7704 return cfg80211_vendor_cmd_reply(reply_skb);
7705}
7706
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307707#define BEACON_MISS_THRESH_2_4 \
7708 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7709#define BEACON_MISS_THRESH_5_0 \
7710 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307711#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7712#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7713#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7714#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307715#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7716 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307717
7718/**
7719 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7720 * vendor command
7721 *
7722 * @wiphy: wiphy device pointer
7723 * @wdev: wireless device pointer
7724 * @data: Vendor command data buffer
7725 * @data_len: Buffer length
7726 *
7727 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7728 *
7729 * Return: EOK or other error codes.
7730 */
7731
7732static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7733 struct wireless_dev *wdev,
7734 const void *data,
7735 int data_len)
7736{
7737 struct net_device *dev = wdev->netdev;
7738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7739 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7740 hdd_station_ctx_t *pHddStaCtx;
7741 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7742 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307743 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307744 eHalStatus status;
7745 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307746 uint8_t hb_thresh_val;
7747
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307748 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7749 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7750 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307751 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7752 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7753 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307754 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7755 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307756 };
7757
7758 ENTER();
7759
7760 if (VOS_FTM_MODE == hdd_get_conparam()) {
7761 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7762 return -EINVAL;
7763 }
7764
7765 ret_val = wlan_hdd_validate_context(pHddCtx);
7766 if (ret_val) {
7767 return ret_val;
7768 }
7769
7770 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7771
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307772 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7773 hddLog(LOGE, FL("Invalid ATTR"));
7774 return -EINVAL;
7775 }
7776
7777 /* check the Wifi Capability */
7778 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7779 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7780 {
7781 hddLog(VOS_TRACE_LEVEL_ERROR,
7782 FL("WIFICONFIG not supported by Firmware"));
7783 return -EINVAL;
7784 }
7785
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307786 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7787 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7788 modifyRoamParamsReq.value =
7789 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7790
7791 if (eHAL_STATUS_SUCCESS !=
7792 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7793 {
7794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7795 ret_val = -EINVAL;
7796 }
7797 return ret_val;
7798 }
7799
7800 /* Moved this down in order to provide provision to set beacon
7801 * miss penalty count irrespective of connection state.
7802 */
7803 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7804 hddLog(LOGE, FL("Not in Connected state!"));
7805 return -ENOTSUPP;
7806 }
7807
7808 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307809
7810 if (!pReq) {
7811 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7812 "%s: Not able to allocate memory for tSetWifiConfigParams",
7813 __func__);
7814 return eHAL_STATUS_E_MALLOC_FAILED;
7815 }
7816
7817 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7818
7819 pReq->sessionId = pAdapter->sessionId;
7820 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7821
7822 if (tb[PARAM_MODULATED_DTIM]) {
7823 pReq->paramValue = nla_get_u32(
7824 tb[PARAM_MODULATED_DTIM]);
7825 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7826 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307827 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307828 hdd_set_pwrparams(pHddCtx);
7829 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7830 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7831
7832 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7833 iw_full_power_cbfn, pAdapter,
7834 eSME_FULL_PWR_NEEDED_BY_HDD);
7835 }
7836 else
7837 {
7838 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7839 }
7840 }
7841
7842 if (tb[PARAM_STATS_AVG_FACTOR]) {
7843 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7844 pReq->paramValue = nla_get_u16(
7845 tb[PARAM_STATS_AVG_FACTOR]);
7846 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7847 pReq->paramType, pReq->paramValue);
7848 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7849
7850 if (eHAL_STATUS_SUCCESS != status)
7851 {
7852 vos_mem_free(pReq);
7853 pReq = NULL;
7854 ret_val = -EPERM;
7855 return ret_val;
7856 }
7857 }
7858
7859
7860 if (tb[PARAM_GUARD_TIME]) {
7861 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7862 pReq->paramValue = nla_get_u32(
7863 tb[PARAM_GUARD_TIME]);
7864 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7865 pReq->paramType, pReq->paramValue);
7866 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7867
7868 if (eHAL_STATUS_SUCCESS != status)
7869 {
7870 vos_mem_free(pReq);
7871 pReq = NULL;
7872 ret_val = -EPERM;
7873 return ret_val;
7874 }
7875
7876 }
7877
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307878 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7879 hb_thresh_val = nla_get_u8(
7880 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7881
7882 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7883 hb_thresh_val);
7884 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7885 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7886 NULL, eANI_BOOLEAN_FALSE);
7887
7888 status = sme_update_hb_threshold(
7889 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7890 WNI_CFG_HEART_BEAT_THRESHOLD,
7891 hb_thresh_val, eCSR_BAND_24);
7892 if (eHAL_STATUS_SUCCESS != status) {
7893 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7894 vos_mem_free(pReq);
7895 pReq = NULL;
7896 return -EPERM;
7897 }
7898 }
7899
7900 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7901 hb_thresh_val = nla_get_u8(
7902 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7903
7904 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7905 hb_thresh_val);
7906 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7907 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7908 NULL, eANI_BOOLEAN_FALSE);
7909
7910 status = sme_update_hb_threshold(
7911 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7912 WNI_CFG_HEART_BEAT_THRESHOLD,
7913 hb_thresh_val, eCSR_BAND_5G);
7914 if (eHAL_STATUS_SUCCESS != status) {
7915 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7916 vos_mem_free(pReq);
7917 pReq = NULL;
7918 return -EPERM;
7919 }
7920 }
7921
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307922 EXIT();
7923 return ret_val;
7924}
7925
7926/**
7927 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7928 * vendor command
7929 *
7930 * @wiphy: wiphy device pointer
7931 * @wdev: wireless device pointer
7932 * @data: Vendor command data buffer
7933 * @data_len: Buffer length
7934 *
7935 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7936 *
7937 * Return: EOK or other error codes.
7938 */
7939static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7940 struct wireless_dev *wdev,
7941 const void *data,
7942 int data_len)
7943{
7944 int ret;
7945
7946 vos_ssr_protect(__func__);
7947 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7948 data, data_len);
7949 vos_ssr_unprotect(__func__);
7950
7951 return ret;
7952}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307953
7954/*
7955 * define short names for the global vendor params
7956 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7957 */
7958#define STATS_SET_INVALID \
7959 QCA_ATTR_NUD_STATS_SET_INVALID
7960#define STATS_SET_START \
7961 QCA_ATTR_NUD_STATS_SET_START
7962#define STATS_GW_IPV4 \
7963 QCA_ATTR_NUD_STATS_GW_IPV4
7964#define STATS_SET_MAX \
7965 QCA_ATTR_NUD_STATS_SET_MAX
7966
7967const struct nla_policy
7968qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7969{
7970 [STATS_SET_START] = {.type = NLA_FLAG },
7971 [STATS_GW_IPV4] = {.type = NLA_U32 },
7972};
7973
7974/**
7975 * hdd_set_nud_stats_cb() - hdd callback api to get status
7976 * @data: pointer to adapter
7977 * @rsp: status
7978 *
7979 * Return: None
7980 */
7981static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7982{
7983
7984 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7985
7986 if (NULL == adapter)
7987 return;
7988
7989 if (VOS_STATUS_SUCCESS == rsp) {
7990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7991 "%s success received STATS_SET_START", __func__);
7992 } else {
7993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7994 "%s STATS_SET_START Failed!!", __func__);
7995 }
7996 return;
7997}
7998
7999/**
8000 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8001 * @wiphy: pointer to wireless wiphy structure.
8002 * @wdev: pointer to wireless_dev structure.
8003 * @data: pointer to apfind configuration data.
8004 * @data_len: the length in byte of apfind data.
8005 *
8006 * This is called when wlan driver needs to send arp stats to
8007 * firmware.
8008 *
8009 * Return: An error code or 0 on success.
8010 */
8011static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8012 struct wireless_dev *wdev,
8013 const void *data, int data_len)
8014{
8015 struct nlattr *tb[STATS_SET_MAX + 1];
8016 struct net_device *dev = wdev->netdev;
8017 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8018 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308019 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308020 setArpStatsParams arp_stats_params;
8021 int err = 0;
8022
8023 ENTER();
8024
8025 err = wlan_hdd_validate_context(hdd_ctx);
8026 if (0 != err)
8027 return err;
8028
8029 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8031 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8032 return -EINVAL;
8033 }
8034
8035 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8036 qca_wlan_vendor_set_nud_stats);
8037 if (err)
8038 {
8039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8040 "%s STATS_SET_START ATTR", __func__);
8041 return err;
8042 }
8043
8044 if (tb[STATS_SET_START])
8045 {
8046 if (!tb[STATS_GW_IPV4]) {
8047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8048 "%s STATS_SET_START CMD", __func__);
8049 return -EINVAL;
8050 }
8051 arp_stats_params.flag = true;
8052 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8053 } else {
8054 arp_stats_params.flag = false;
8055 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308056 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8058 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308059 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8060 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308061
8062 arp_stats_params.pkt_type = 1; // ARP packet type
8063
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308064 if (arp_stats_params.flag) {
8065 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8066 WLANTL_SetARPFWDatapath(pVosContext, true);
8067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8068 "%s Set FW in data path for ARP with tgt IP :%d",
8069 __func__, hdd_ctx->track_arp_ip);
8070 }
8071 else {
8072 WLANTL_SetARPFWDatapath(pVosContext, false);
8073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8074 "%s Remove FW from data path", __func__);
8075 }
8076
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308077 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8078 arp_stats_params.data_ctx = adapter;
8079
8080 if (eHAL_STATUS_SUCCESS !=
8081 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8083 "%s STATS_SET_START CMD Failed!!", __func__);
8084 return -EINVAL;
8085 }
8086
8087 EXIT();
8088
8089 return err;
8090}
8091
8092/**
8093 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8094 * @wiphy: pointer to wireless wiphy structure.
8095 * @wdev: pointer to wireless_dev structure.
8096 * @data: pointer to apfind configuration data.
8097 * @data_len: the length in byte of apfind data.
8098 *
8099 * This is called when wlan driver needs to send arp stats to
8100 * firmware.
8101 *
8102 * Return: An error code or 0 on success.
8103 */
8104static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8105 struct wireless_dev *wdev,
8106 const void *data, int data_len)
8107{
8108 int ret;
8109
8110 vos_ssr_protect(__func__);
8111 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8112 vos_ssr_unprotect(__func__);
8113
8114 return ret;
8115}
8116#undef STATS_SET_INVALID
8117#undef STATS_SET_START
8118#undef STATS_GW_IPV4
8119#undef STATS_SET_MAX
8120
8121/*
8122 * define short names for the global vendor params
8123 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8124 */
8125#define STATS_GET_INVALID \
8126 QCA_ATTR_NUD_STATS_SET_INVALID
8127#define COUNT_FROM_NETDEV \
8128 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8129#define COUNT_TO_LOWER_MAC \
8130 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8131#define RX_COUNT_BY_LOWER_MAC \
8132 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8133#define COUNT_TX_SUCCESS \
8134 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8135#define RSP_RX_COUNT_BY_LOWER_MAC \
8136 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8137#define RSP_RX_COUNT_BY_UPPER_MAC \
8138 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8139#define RSP_COUNT_TO_NETDEV \
8140 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8141#define RSP_COUNT_OUT_OF_ORDER_DROP \
8142 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8143#define AP_LINK_ACTIVE \
8144 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8145#define AP_LINK_DAD \
8146 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8147#define STATS_GET_MAX \
8148 QCA_ATTR_NUD_STATS_GET_MAX
8149
8150const struct nla_policy
8151qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8152{
8153 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8154 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8155 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8156 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8157 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8158 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8159 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8160 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8161 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8162 [AP_LINK_DAD] = {.type = NLA_FLAG },
8163};
8164
8165static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8166{
8167
8168 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8169 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8170 struct hdd_nud_stats_context *context;
8171 int status;
8172
8173 ENTER();
8174
8175 if (NULL == adapter)
8176 return;
8177
8178 status = wlan_hdd_validate_context(hdd_ctx);
8179 if (0 != status) {
8180 return;
8181 }
8182
8183 if (!rsp) {
8184 hddLog(LOGE, FL("data is null"));
8185 return;
8186 }
8187
8188 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8189 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8190 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8191 adapter->dad |= rsp->dad;
8192
8193 spin_lock(&hdd_context_lock);
8194 context = &hdd_ctx->nud_stats_context;
8195 complete(&context->response_event);
8196 spin_unlock(&hdd_context_lock);
8197
8198 return;
8199}
8200static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8201 struct wireless_dev *wdev,
8202 const void *data, int data_len)
8203{
8204 int err = 0;
8205 unsigned long rc;
8206 struct hdd_nud_stats_context *context;
8207 struct net_device *dev = wdev->netdev;
8208 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8209 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8210 getArpStatsParams arp_stats_params;
8211 struct sk_buff *skb;
8212
8213 ENTER();
8214
8215 err = wlan_hdd_validate_context(hdd_ctx);
8216 if (0 != err)
8217 return err;
8218
8219 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8220 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8221 arp_stats_params.data_ctx = adapter;
8222
8223 spin_lock(&hdd_context_lock);
8224 context = &hdd_ctx->nud_stats_context;
8225 INIT_COMPLETION(context->response_event);
8226 spin_unlock(&hdd_context_lock);
8227
8228 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8230 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8231 return -EINVAL;
8232 }
8233
8234 if (eHAL_STATUS_SUCCESS !=
8235 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8237 "%s STATS_SET_START CMD Failed!!", __func__);
8238 return -EINVAL;
8239 }
8240
8241 rc = wait_for_completion_timeout(&context->response_event,
8242 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8243 if (!rc)
8244 {
8245 hddLog(LOGE,
8246 FL("Target response timed out request "));
8247 return -ETIMEDOUT;
8248 }
8249
8250 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8251 WLAN_NUD_STATS_LEN);
8252 if (!skb)
8253 {
8254 hddLog(VOS_TRACE_LEVEL_ERROR,
8255 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8256 __func__);
8257 return -ENOMEM;
8258 }
8259
8260 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8261 adapter->hdd_stats.hddArpStats.txCount) ||
8262 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8263 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8264 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8265 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8266 nla_put_u16(skb, COUNT_TX_SUCCESS,
8267 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8268 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8269 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8270 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8271 adapter->hdd_stats.hddArpStats.rxCount) ||
8272 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8273 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8274 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8275 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8276 hddLog(LOGE, FL("nla put fail"));
8277 kfree_skb(skb);
8278 return -EINVAL;
8279 }
8280 if (adapter->con_status)
8281 nla_put_flag(skb, AP_LINK_ACTIVE);
8282 if (adapter->dad)
8283 nla_put_flag(skb, AP_LINK_DAD);
8284
8285 cfg80211_vendor_cmd_reply(skb);
8286 return err;
8287}
8288
8289static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8290 struct wireless_dev *wdev,
8291 const void *data, int data_len)
8292{
8293 int ret;
8294
8295 vos_ssr_protect(__func__);
8296 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8297 vos_ssr_unprotect(__func__);
8298
8299 return ret;
8300}
8301
8302#undef QCA_ATTR_NUD_STATS_SET_INVALID
8303#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8304#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8305#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8306#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8307#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8308#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8309#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8310#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8311#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8312#undef QCA_ATTR_NUD_STATS_GET_MAX
8313
8314
8315
Kapil Guptaee33bf12016-12-20 18:27:37 +05308316#ifdef WLAN_FEATURE_APFIND
8317/**
8318 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8319 * @wiphy: pointer to wireless wiphy structure.
8320 * @wdev: pointer to wireless_dev structure.
8321 * @data: pointer to apfind configuration data.
8322 * @data_len: the length in byte of apfind data.
8323 *
8324 * This is called when wlan driver needs to send APFIND configurations to
8325 * firmware.
8326 *
8327 * Return: An error code or 0 on success.
8328 */
8329static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8330 struct wireless_dev *wdev,
8331 const void *data, int data_len)
8332{
8333 struct sme_ap_find_request_req apfind_req;
8334 VOS_STATUS status;
8335 int ret_val;
8336 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8337
8338 ENTER();
8339
8340 ret_val = wlan_hdd_validate_context(hdd_ctx);
8341 if (ret_val)
8342 return ret_val;
8343
8344 if (VOS_FTM_MODE == hdd_get_conparam()) {
8345 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8346 return -EPERM;
8347 }
8348
8349 apfind_req.request_data_len = data_len;
8350 apfind_req.request_data = data;
8351
8352 status = sme_apfind_set_cmd(&apfind_req);
8353 if (VOS_STATUS_SUCCESS != status) {
8354 ret_val = -EIO;
8355 }
8356 return ret_val;
8357}
8358
8359/**
8360 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8361 * @wiphy: pointer to wireless wiphy structure.
8362 * @wdev: pointer to wireless_dev structure.
8363 * @data: pointer to apfind configuration data.
8364 * @data_len: the length in byte of apfind data.
8365 *
8366 * This is called when wlan driver needs to send APFIND configurations to
8367 * firmware.
8368 *
8369 * Return: An error code or 0 on success.
8370 */
8371static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8372 struct wireless_dev *wdev,
8373 const void *data, int data_len)
8374{
8375 int ret;
8376
8377 vos_ssr_protect(__func__);
8378 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8379 vos_ssr_unprotect(__func__);
8380
8381 return ret;
8382}
8383#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308384const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8385{
Mukul Sharma2a271632014-10-13 14:59:01 +05308386 {
8387 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8388 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8389 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8390 WIPHY_VENDOR_CMD_NEED_NETDEV |
8391 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308392 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308393 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308394
8395 {
8396 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8397 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8398 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8399 WIPHY_VENDOR_CMD_NEED_NETDEV |
8400 WIPHY_VENDOR_CMD_NEED_RUNNING,
8401 .doit = wlan_hdd_cfg80211_nan_request
8402 },
8403
Sunil Duttc69bccb2014-05-26 21:30:20 +05308404#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8405 {
8406 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8407 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8408 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8409 WIPHY_VENDOR_CMD_NEED_NETDEV |
8410 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308411 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308412 },
8413
8414 {
8415 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8416 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8417 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8418 WIPHY_VENDOR_CMD_NEED_NETDEV |
8419 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308420 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308421 },
8422
8423 {
8424 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8425 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8426 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8427 WIPHY_VENDOR_CMD_NEED_NETDEV |
8428 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308429 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308430 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308431#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308432#ifdef WLAN_FEATURE_EXTSCAN
8433 {
8434 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8435 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8436 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8437 WIPHY_VENDOR_CMD_NEED_NETDEV |
8438 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308439 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308440 },
8441 {
8442 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8443 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8444 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8445 WIPHY_VENDOR_CMD_NEED_NETDEV |
8446 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308447 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308448 },
8449 {
8450 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8451 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8452 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8453 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308454 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308455 },
8456 {
8457 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8458 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8459 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8460 WIPHY_VENDOR_CMD_NEED_NETDEV |
8461 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308462 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308463 },
8464 {
8465 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8466 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8467 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8468 WIPHY_VENDOR_CMD_NEED_NETDEV |
8469 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308470 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308471 },
8472 {
8473 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8474 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8475 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8476 WIPHY_VENDOR_CMD_NEED_NETDEV |
8477 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308478 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308479 },
8480 {
8481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8484 WIPHY_VENDOR_CMD_NEED_NETDEV |
8485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308486 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308487 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308488#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308489/*EXT TDLS*/
8490 {
8491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8494 WIPHY_VENDOR_CMD_NEED_NETDEV |
8495 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308496 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308497 },
8498 {
8499 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8500 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8501 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8502 WIPHY_VENDOR_CMD_NEED_NETDEV |
8503 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308504 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308505 },
8506 {
8507 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8508 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8509 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8510 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308511 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308512 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308513 {
8514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8517 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308518 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308519 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308520 {
8521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8524 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308526 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308527 {
8528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8531 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308532 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308533 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308534 {
8535 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8536 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8537 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8538 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308539 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308540 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308541 {
8542 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308543 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8544 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8545 WIPHY_VENDOR_CMD_NEED_NETDEV |
8546 WIPHY_VENDOR_CMD_NEED_RUNNING,
8547 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8548 },
8549 {
8550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8553 WIPHY_VENDOR_CMD_NEED_NETDEV |
8554 WIPHY_VENDOR_CMD_NEED_RUNNING,
8555 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308556 },
8557 {
8558 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8559 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8560 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8561 WIPHY_VENDOR_CMD_NEED_NETDEV,
8562 .doit = wlan_hdd_cfg80211_wifi_logger_start
8563 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308564 {
8565 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8566 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8567 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8568 WIPHY_VENDOR_CMD_NEED_NETDEV|
8569 WIPHY_VENDOR_CMD_NEED_RUNNING,
8570 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308571 },
8572 {
8573 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8574 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8575 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8576 WIPHY_VENDOR_CMD_NEED_NETDEV |
8577 WIPHY_VENDOR_CMD_NEED_RUNNING,
8578 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308579 },
8580 {
8581 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8582 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8583 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8584 WIPHY_VENDOR_CMD_NEED_NETDEV |
8585 WIPHY_VENDOR_CMD_NEED_RUNNING,
8586 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308587 },
8588#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8589 {
8590 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8591 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8592 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8593 WIPHY_VENDOR_CMD_NEED_NETDEV |
8594 WIPHY_VENDOR_CMD_NEED_RUNNING,
8595 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308596 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308597#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308598 {
8599 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8600 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8601 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8602 WIPHY_VENDOR_CMD_NEED_NETDEV |
8603 WIPHY_VENDOR_CMD_NEED_RUNNING,
8604 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308605 },
8606 {
8607 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8608 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8609 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8610 WIPHY_VENDOR_CMD_NEED_NETDEV |
8611 WIPHY_VENDOR_CMD_NEED_RUNNING,
8612 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308613 },
8614#ifdef WLAN_FEATURE_APFIND
8615 {
8616 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8617 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8618 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8619 WIPHY_VENDOR_CMD_NEED_NETDEV,
8620 .doit = wlan_hdd_cfg80211_apfind_cmd
8621 },
8622#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308623 {
8624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8627 WIPHY_VENDOR_CMD_NEED_NETDEV |
8628 WIPHY_VENDOR_CMD_NEED_RUNNING,
8629 .doit = wlan_hdd_cfg80211_set_nud_stats
8630 },
8631 {
8632 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8633 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8634 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8635 WIPHY_VENDOR_CMD_NEED_NETDEV |
8636 WIPHY_VENDOR_CMD_NEED_RUNNING,
8637 .doit = wlan_hdd_cfg80211_get_nud_stats
8638 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308639 {
8640 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8641 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8642 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8643 WIPHY_VENDOR_CMD_NEED_NETDEV |
8644 WIPHY_VENDOR_CMD_NEED_RUNNING,
8645 .doit = hdd_cfg80211_get_station_cmd
8646 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308647};
8648
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008649/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308650static const
8651struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008652{
8653#ifdef FEATURE_WLAN_CH_AVOID
8654 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308655 .vendor_id = QCA_NL80211_VENDOR_ID,
8656 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008657 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308658#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8659#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8660 {
8661 /* Index = 1*/
8662 .vendor_id = QCA_NL80211_VENDOR_ID,
8663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8664 },
8665 {
8666 /* Index = 2*/
8667 .vendor_id = QCA_NL80211_VENDOR_ID,
8668 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8669 },
8670 {
8671 /* Index = 3*/
8672 .vendor_id = QCA_NL80211_VENDOR_ID,
8673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8674 },
8675 {
8676 /* Index = 4*/
8677 .vendor_id = QCA_NL80211_VENDOR_ID,
8678 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8679 },
8680 {
8681 /* Index = 5*/
8682 .vendor_id = QCA_NL80211_VENDOR_ID,
8683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8684 },
8685 {
8686 /* Index = 6*/
8687 .vendor_id = QCA_NL80211_VENDOR_ID,
8688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8689 },
8690#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308691#ifdef WLAN_FEATURE_EXTSCAN
8692 {
8693 .vendor_id = QCA_NL80211_VENDOR_ID,
8694 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8695 },
8696 {
8697 .vendor_id = QCA_NL80211_VENDOR_ID,
8698 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8699 },
8700 {
8701 .vendor_id = QCA_NL80211_VENDOR_ID,
8702 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8703 },
8704 {
8705 .vendor_id = QCA_NL80211_VENDOR_ID,
8706 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8707 },
8708 {
8709 .vendor_id = QCA_NL80211_VENDOR_ID,
8710 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8711 },
8712 {
8713 .vendor_id = QCA_NL80211_VENDOR_ID,
8714 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8715 },
8716 {
8717 .vendor_id = QCA_NL80211_VENDOR_ID,
8718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8719 },
8720 {
8721 .vendor_id = QCA_NL80211_VENDOR_ID,
8722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8723 },
8724 {
8725 .vendor_id = QCA_NL80211_VENDOR_ID,
8726 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8727 },
8728 {
8729 .vendor_id = QCA_NL80211_VENDOR_ID,
8730 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8731 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308732#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308733/*EXT TDLS*/
8734 {
8735 .vendor_id = QCA_NL80211_VENDOR_ID,
8736 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8737 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308738 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8739 .vendor_id = QCA_NL80211_VENDOR_ID,
8740 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8741 },
8742
Srinivas Dasari030bad32015-02-18 23:23:54 +05308743
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308744 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308745 .vendor_id = QCA_NL80211_VENDOR_ID,
8746 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8747 },
8748
Sushant Kaushik084f6592015-09-10 13:11:56 +05308749 {
8750 .vendor_id = QCA_NL80211_VENDOR_ID,
8751 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308752 },
8753 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8754 .vendor_id = QCA_NL80211_VENDOR_ID,
8755 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8756 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308757 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8758 .vendor_id = QCA_NL80211_VENDOR_ID,
8759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8760 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308761 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8762 .vendor_id = QCA_NL80211_VENDOR_ID,
8763 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8764 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008765};
8766
Jeff Johnson295189b2012-06-20 16:38:30 -07008767/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308768 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308769 * This function is called by hdd_wlan_startup()
8770 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308771 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308773struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008774{
8775 struct wiphy *wiphy;
8776 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308777 /*
8778 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 */
8780 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8781
8782 if (!wiphy)
8783 {
8784 /* Print error and jump into err label and free the memory */
8785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8786 return NULL;
8787 }
8788
Sunil Duttc69bccb2014-05-26 21:30:20 +05308789
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 return wiphy;
8791}
8792
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308793#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8794 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8795/**
8796 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8797 * @wiphy: pointer to wiphy
8798 * @config: pointer to config
8799 *
8800 * Return: None
8801 */
8802static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8803 hdd_config_t *config)
8804{
8805 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8806 if (config->max_sched_scan_plan_interval)
8807 wiphy->max_sched_scan_plan_interval =
8808 config->max_sched_scan_plan_interval;
8809 if (config->max_sched_scan_plan_iterations)
8810 wiphy->max_sched_scan_plan_iterations =
8811 config->max_sched_scan_plan_iterations;
8812}
8813#else
8814static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8815 hdd_config_t *config)
8816{
8817}
8818#endif
8819
Jeff Johnson295189b2012-06-20 16:38:30 -07008820/*
8821 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308822 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 * private ioctl to change the band value
8824 */
8825int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8826{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308827 int i, j;
8828 eNVChannelEnabledType channelEnabledState;
8829
Jeff Johnsone7245742012-09-05 17:12:55 -07008830 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308831
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308832 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308834
8835 if (NULL == wiphy->bands[i])
8836 {
8837 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8838 __func__, i);
8839 continue;
8840 }
8841
8842 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8843 {
8844 struct ieee80211_supported_band *band = wiphy->bands[i];
8845
8846 channelEnabledState = vos_nv_getChannelEnabledState(
8847 band->channels[j].hw_value);
8848
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308849 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308850 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308851 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308852 continue;
8853 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308854 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308855 {
8856 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8857 continue;
8858 }
8859
8860 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8861 NV_CHANNEL_INVALID == channelEnabledState)
8862 {
8863 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8864 }
8865 else if (NV_CHANNEL_DFS == channelEnabledState)
8866 {
8867 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8868 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8869 }
8870 else
8871 {
8872 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8873 |IEEE80211_CHAN_RADAR);
8874 }
8875 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 }
8877 return 0;
8878}
8879/*
8880 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 * This function is called by hdd_wlan_startup()
8882 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 * This function is used to initialize and register wiphy structure.
8884 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308885int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 struct wiphy *wiphy,
8887 hdd_config_t *pCfg
8888 )
8889{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308890 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308891 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8892
Jeff Johnsone7245742012-09-05 17:12:55 -07008893 ENTER();
8894
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 /* Now bind the underlying wlan device with wiphy */
8896 set_wiphy_dev(wiphy, dev);
8897
8898 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008899
Kiet Lam6c583332013-10-14 05:37:09 +05308900#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008901 /* the flag for the other case would be initialzed in
8902 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308903#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8904 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8905#else
Amar Singhal0a402232013-10-11 20:57:16 -07008906 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308907#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308908#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008909
Amar Singhalfddc28c2013-09-05 13:03:40 -07008910 /* This will disable updating of NL channels from passive to
8911 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308912#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8913 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8914#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008915 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308916#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008917
Amar Singhala49cbc52013-10-08 18:37:44 -07008918
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008920 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8921 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8922 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008923 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308925 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308926#else
8927 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8928#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008929#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008930
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008931#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008932 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008933#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008934 || pCfg->isFastRoamIniFeatureEnabled
8935#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008936#ifdef FEATURE_WLAN_ESE
8937 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008938#endif
8939 )
8940 {
8941 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8942 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008943#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008944#ifdef FEATURE_WLAN_TDLS
8945 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8946 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8947#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308948#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308949 if (pCfg->configPNOScanSupport)
8950 {
8951 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8952 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8953 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8954 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8955 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308956#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008957
Abhishek Singh10d85972015-04-17 10:27:23 +05308958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8959 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8960#endif
8961
Amar Singhalfddc28c2013-09-05 13:03:40 -07008962#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008963 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8964 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008965 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008966 driver need to determine what to do with both
8967 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008968
8969 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008970#else
8971 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008972#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008973
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308974 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8975
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308976 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008977
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308978 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8979
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308981 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8982 | BIT(NL80211_IFTYPE_ADHOC)
8983 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8984 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308985 | BIT(NL80211_IFTYPE_AP)
8986 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07008987
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308988 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008989 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8991 if( pCfg->enableMCC )
8992 {
8993 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308994 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008995
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308996 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308997 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008998
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308999 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309000 wiphy->iface_combinations = wlan_hdd_iface_combination;
9001 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009002#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309003 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009004
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 /* Before registering we need to update the ht capabilitied based
9006 * on ini values*/
9007 if( !pCfg->ShortGI20MhzEnable )
9008 {
9009 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9010 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009011 }
9012
9013 if( !pCfg->ShortGI40MhzEnable )
9014 {
9015 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9016 }
9017
9018 if( !pCfg->nChannelBondingMode5GHz )
9019 {
9020 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9021 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309022 /*
9023 * In case of static linked driver at the time of driver unload,
9024 * module exit doesn't happens. Module cleanup helps in cleaning
9025 * of static memory.
9026 * If driver load happens statically, at the time of driver unload,
9027 * wiphy flags don't get reset because of static memory.
9028 * It's better not to store channel in static memory.
9029 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309030 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9031 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309032 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309033 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309034 {
9035 hddLog(VOS_TRACE_LEVEL_ERROR,
9036 FL("Not enough memory to allocate channels"));
9037 return -ENOMEM;
9038 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309039 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309040 &hdd_channels_2_4_GHZ[0],
9041 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009042
Agrawal Ashish97dec502015-11-26 20:20:58 +05309043 if (true == hdd_is_5g_supported(pHddCtx))
9044 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309045 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9046 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309047 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309048 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309049 {
9050 hddLog(VOS_TRACE_LEVEL_ERROR,
9051 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309052 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9053 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309054 return -ENOMEM;
9055 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309056 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309057 &hdd_channels_5_GHZ[0],
9058 sizeof(hdd_channels_5_GHZ));
9059 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309060
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309061 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309062 {
9063
9064 if (NULL == wiphy->bands[i])
9065 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309066 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309067 __func__, i);
9068 continue;
9069 }
9070
9071 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9072 {
9073 struct ieee80211_supported_band *band = wiphy->bands[i];
9074
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309075 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309076 {
9077 // Enable social channels for P2P
9078 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9079 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9080 else
9081 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9082 continue;
9083 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309084 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309085 {
9086 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9087 continue;
9088 }
9089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009090 }
9091 /*Initialise the supported cipher suite details*/
9092 wiphy->cipher_suites = hdd_cipher_suites;
9093 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9094
9095 /*signal strength in mBm (100*dBm) */
9096 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9097
9098#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309099 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009101
Sunil Duttc69bccb2014-05-26 21:30:20 +05309102 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9103 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009104 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9105 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9106
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309107 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9108
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309109 EXIT();
9110 return 0;
9111}
9112
9113/* In this function we are registering wiphy. */
9114int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9115{
9116 ENTER();
9117 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 if (0 > wiphy_register(wiphy))
9119 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309120 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9122 return -EIO;
9123 }
9124
9125 EXIT();
9126 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309127}
Jeff Johnson295189b2012-06-20 16:38:30 -07009128
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309129/* In this function we are updating channel list when,
9130 regulatory domain is FCC and country code is US.
9131 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9132 As per FCC smart phone is not a indoor device.
9133 GO should not opeate on indoor channels */
9134void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9135{
9136 int j;
9137 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9138 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9139 //Default counrtycode from NV at the time of wiphy initialization.
9140 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9141 &defaultCountryCode[0]))
9142 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009143 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309144 }
9145 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9146 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309147 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309148 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309149 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309150 return;
9151 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309152 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309153 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309154 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309155 // Mark UNII -1 band channel as passive
9156 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9157 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9158 }
9159 }
9160}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309161/* This function registers for all frame which supplicant is interested in */
9162void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009163{
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9165 /* Register for all P2P action, public action etc frames */
9166 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009167 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309168 /* Register frame indication call back */
9169 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 /* Right now we are registering these frame when driver is getting
9171 initialized. Once we will move to 2.6.37 kernel, in which we have
9172 frame register ops, we will move this code as a part of that */
9173 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309174 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9176
9177 /* GAS Initial Response */
9178 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9179 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309180
Jeff Johnson295189b2012-06-20 16:38:30 -07009181 /* GAS Comeback Request */
9182 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9183 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9184
9185 /* GAS Comeback Response */
9186 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9187 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9188
9189 /* P2P Public Action */
9190 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309191 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 P2P_PUBLIC_ACTION_FRAME_SIZE );
9193
9194 /* P2P Action */
9195 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9196 (v_U8_t*)P2P_ACTION_FRAME,
9197 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009198
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309199 /* WNM BSS Transition Request frame */
9200 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9201 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9202 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009203
9204 /* WNM-Notification */
9205 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9206 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9207 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009208}
9209
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309210void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009211{
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9213 /* Register for all P2P action, public action etc frames */
9214 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9215
Jeff Johnsone7245742012-09-05 17:12:55 -07009216 ENTER();
9217
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 /* Right now we are registering these frame when driver is getting
9219 initialized. Once we will move to 2.6.37 kernel, in which we have
9220 frame register ops, we will move this code as a part of that */
9221 /* GAS Initial Request */
9222
9223 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9224 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9225
9226 /* GAS Initial Response */
9227 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9228 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309229
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 /* GAS Comeback Request */
9231 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9232 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9233
9234 /* GAS Comeback Response */
9235 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9236 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9237
9238 /* P2P Public Action */
9239 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309240 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 P2P_PUBLIC_ACTION_FRAME_SIZE );
9242
9243 /* P2P Action */
9244 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9245 (v_U8_t*)P2P_ACTION_FRAME,
9246 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009247 /* WNM-Notification */
9248 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9249 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9250 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009251}
9252
9253#ifdef FEATURE_WLAN_WAPI
9254void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309255 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009256{
9257 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9258 tCsrRoamSetKey setKey;
9259 v_BOOL_t isConnected = TRUE;
9260 int status = 0;
9261 v_U32_t roamId= 0xFF;
9262 tANI_U8 *pKeyPtr = NULL;
9263 int n = 0;
9264
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9266 __func__, hdd_device_modetoString(pAdapter->device_mode),
9267 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009268
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309269 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 setKey.keyId = key_index; // Store Key ID
9271 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9272 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9273 setKey.paeRole = 0 ; // the PAE role
9274 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9275 {
9276 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9277 }
9278 else
9279 {
9280 isConnected = hdd_connIsConnected(pHddStaCtx);
9281 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9282 }
9283 setKey.keyLength = key_Len;
9284 pKeyPtr = setKey.Key;
9285 memcpy( pKeyPtr, key, key_Len);
9286
Arif Hussain6d2a3322013-11-17 19:50:10 -08009287 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 __func__, key_Len);
9289 for (n = 0 ; n < key_Len; n++)
9290 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9291 __func__,n,setKey.Key[n]);
9292
9293 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9294 if ( isConnected )
9295 {
9296 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9297 pAdapter->sessionId, &setKey, &roamId );
9298 }
9299 if ( status != 0 )
9300 {
9301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9302 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9303 __LINE__, status );
9304 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9305 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309306 /* Need to clear any trace of key value in the memory.
9307 * Thus zero out the memory even though it is local
9308 * variable.
9309 */
9310 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009311}
9312#endif /* FEATURE_WLAN_WAPI*/
9313
9314#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309315int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 beacon_data_t **ppBeacon,
9317 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009318#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309319int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009320 beacon_data_t **ppBeacon,
9321 struct cfg80211_beacon_data *params,
9322 int dtim_period)
9323#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309324{
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 int size;
9326 beacon_data_t *beacon = NULL;
9327 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309328 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9329 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009330
Jeff Johnsone7245742012-09-05 17:12:55 -07009331 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309333 {
9334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9335 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009338
9339 old = pAdapter->sessionCtx.ap.beacon;
9340
9341 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309342 {
9343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9344 FL("session(%d) old and new heads points to NULL"),
9345 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309347 }
9348
9349 if (params->tail && !params->tail_len)
9350 {
9351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9352 FL("tail_len is zero but tail is not NULL"));
9353 return -EINVAL;
9354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009355
Jeff Johnson295189b2012-06-20 16:38:30 -07009356#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9357 /* Kernel 3.0 is not updating dtim_period for set beacon */
9358 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309359 {
9360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9361 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009362 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009364#endif
9365
Kapil Gupta137ef892016-12-13 19:38:00 +05309366 if (params->head)
9367 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309369 head = params->head;
9370 } else
9371 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309373 head = old->head;
9374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009375
Kapil Gupta137ef892016-12-13 19:38:00 +05309376 if (params->tail || !old)
9377 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309379 tail = params->tail;
9380 } else
9381 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309383 tail = old->tail;
9384 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009385
Kapil Gupta137ef892016-12-13 19:38:00 +05309386 if (params->proberesp_ies || !old)
9387 {
9388 proberesp_ies_len = params->proberesp_ies_len;
9389 proberesp_ies = params->proberesp_ies;
9390 } else
9391 {
9392 proberesp_ies_len = old->proberesp_ies_len;
9393 proberesp_ies = old->proberesp_ies;
9394 }
9395
9396 if (params->assocresp_ies || !old)
9397 {
9398 assocresp_ies_len = params->assocresp_ies_len;
9399 assocresp_ies = params->assocresp_ies;
9400 } else
9401 {
9402 assocresp_ies_len = old->assocresp_ies_len;
9403 assocresp_ies = old->assocresp_ies;
9404 }
9405
9406 size = sizeof(beacon_data_t) + head_len + tail_len +
9407 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009408
9409 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309411 {
9412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9413 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309415 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009416
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009417#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309418 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 beacon->dtim_period = params->dtim_period;
9420 else
9421 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009422#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309423 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009424 beacon->dtim_period = dtim_period;
9425 else
9426 beacon->dtim_period = old->dtim_period;
9427#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9430 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309431 beacon->proberesp_ies = beacon->tail + tail_len;
9432 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9433
Jeff Johnson295189b2012-06-20 16:38:30 -07009434 beacon->head_len = head_len;
9435 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309436 beacon->proberesp_ies_len = proberesp_ies_len;
9437 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
c_manjee527ecac2017-01-25 12:25:27 +05309439 if (head && head_len)
9440 memcpy(beacon->head, head, head_len);
9441 if (tail && tail_len)
9442 memcpy(beacon->tail, tail, tail_len);
9443 if (proberesp_ies && proberesp_ies_len)
9444 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9445 if (assocresp_ies && assocresp_ies_len)
9446 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009447
9448 *ppBeacon = beacon;
9449
9450 kfree(old);
9451
9452 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009453}
Jeff Johnson295189b2012-06-20 16:38:30 -07009454
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309455v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9456#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9457 const v_U8_t *pIes,
9458#else
9459 v_U8_t *pIes,
9460#endif
9461 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009462{
9463 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309464 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309468 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009469 elem_id = ptr[0];
9470 elem_len = ptr[1];
9471 left -= 2;
9472 if(elem_len > left)
9473 {
9474 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009475 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 eid,elem_len,left);
9477 return NULL;
9478 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309479 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 {
9481 return ptr;
9482 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309483
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 left -= elem_len;
9485 ptr += (elem_len + 2);
9486 }
9487 return NULL;
9488}
9489
Jeff Johnson295189b2012-06-20 16:38:30 -07009490/* Check if rate is 11g rate or not */
9491static int wlan_hdd_rate_is_11g(u8 rate)
9492{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009493 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 u8 i;
9495 for (i = 0; i < 8; i++)
9496 {
9497 if(rate == gRateArray[i])
9498 return TRUE;
9499 }
9500 return FALSE;
9501}
9502
9503/* Check for 11g rate and set proper 11g only mode */
9504static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9505 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9506{
9507 u8 i, num_rates = pIe[0];
9508
9509 pIe += 1;
9510 for ( i = 0; i < num_rates; i++)
9511 {
9512 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9513 {
9514 /* If rate set have 11g rate than change the mode to 11G */
9515 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9516 if (pIe[i] & BASIC_RATE_MASK)
9517 {
9518 /* If we have 11g rate as basic rate, it means mode
9519 is 11g only mode.
9520 */
9521 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9522 *pCheckRatesfor11g = FALSE;
9523 }
9524 }
9525 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9526 {
9527 *require_ht = TRUE;
9528 }
9529 }
9530 return;
9531}
9532
9533static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9534{
9535 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9536 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9537 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9538 u8 checkRatesfor11g = TRUE;
9539 u8 require_ht = FALSE;
9540 u8 *pIe=NULL;
9541
9542 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9543
9544 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9545 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9546 if (pIe != NULL)
9547 {
9548 pIe += 1;
9549 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9550 &pConfig->SapHw_mode);
9551 }
9552
9553 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9554 WLAN_EID_EXT_SUPP_RATES);
9555 if (pIe != NULL)
9556 {
9557
9558 pIe += 1;
9559 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9560 &pConfig->SapHw_mode);
9561 }
9562
9563 if( pConfig->channel > 14 )
9564 {
9565 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9566 }
9567
9568 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9569 WLAN_EID_HT_CAPABILITY);
9570
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 {
9573 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9574 if(require_ht)
9575 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9576 }
9577}
9578
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309579static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9580 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9581{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009582 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309583 v_U8_t *pIe = NULL;
9584 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9585
9586 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9587 pBeacon->tail, pBeacon->tail_len);
9588
9589 if (pIe)
9590 {
9591 ielen = pIe[1] + 2;
9592 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9593 {
9594 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9595 }
9596 else
9597 {
9598 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9599 return -EINVAL;
9600 }
9601 *total_ielen += ielen;
9602 }
9603 return 0;
9604}
9605
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009606static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9607 v_U8_t *genie, v_U8_t *total_ielen)
9608{
9609 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9610 int left = pBeacon->tail_len;
9611 v_U8_t *ptr = pBeacon->tail;
9612 v_U8_t elem_id, elem_len;
9613 v_U16_t ielen = 0;
9614
9615 if ( NULL == ptr || 0 == left )
9616 return;
9617
9618 while (left >= 2)
9619 {
9620 elem_id = ptr[0];
9621 elem_len = ptr[1];
9622 left -= 2;
9623 if (elem_len > left)
9624 {
9625 hddLog( VOS_TRACE_LEVEL_ERROR,
9626 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9627 elem_id, elem_len, left);
9628 return;
9629 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309630 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009631 {
9632 /* skipping the VSIE's which we don't want to include or
9633 * it will be included by existing code
9634 */
9635 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9636#ifdef WLAN_FEATURE_WFD
9637 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9638#endif
9639 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9640 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9641 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9642 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9643 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9644 {
9645 ielen = ptr[1] + 2;
9646 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9647 {
9648 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9649 *total_ielen += ielen;
9650 }
9651 else
9652 {
9653 hddLog( VOS_TRACE_LEVEL_ERROR,
9654 "IE Length is too big "
9655 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9656 elem_id, elem_len, *total_ielen);
9657 }
9658 }
9659 }
9660
9661 left -= elem_len;
9662 ptr += (elem_len + 2);
9663 }
9664 return;
9665}
9666
Kapil Gupta137ef892016-12-13 19:38:00 +05309667int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009668{
9669 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309670 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009672 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309673 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009674
9675 genie = vos_mem_malloc(MAX_GENIE_LEN);
9676
9677 if(genie == NULL) {
9678
9679 return -ENOMEM;
9680 }
9681
Kapil Gupta137ef892016-12-13 19:38:00 +05309682 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9684 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309686 hddLog(LOGE,
9687 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309688 ret = -EINVAL;
9689 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 }
9691
9692#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309693 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9694 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9695 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309696 hddLog(LOGE,
9697 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309698 ret = -EINVAL;
9699 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 }
9701#endif
9702
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309703 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9704 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309706 hddLog(LOGE,
9707 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309708 ret = -EINVAL;
9709 goto done;
9710 }
9711
9712 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9713 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009714 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009716
9717 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9718 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9719 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9720 {
9721 hddLog(LOGE,
9722 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009723 ret = -EINVAL;
9724 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 }
9726
9727 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9728 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9729 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9730 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9731 ==eHAL_STATUS_FAILURE)
9732 {
9733 hddLog(LOGE,
9734 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009735 ret = -EINVAL;
9736 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 }
9738
9739 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309740 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009741 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309742 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 u8 probe_rsp_ie_len[3] = {0};
9744 u8 counter = 0;
9745 /* Check Probe Resp Length if it is greater then 255 then Store
9746 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9747 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9748 Store More then 255 bytes into One Variable.
9749 */
9750 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9751 {
9752 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9753 {
9754 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9755 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9756 }
9757 else
9758 {
9759 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9760 rem_probe_resp_ie_len = 0;
9761 }
9762 }
9763
9764 rem_probe_resp_ie_len = 0;
9765
9766 if (probe_rsp_ie_len[0] > 0)
9767 {
9768 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9769 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309770 (tANI_U8*)&pBeacon->
9771 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 probe_rsp_ie_len[0], NULL,
9773 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9774 {
9775 hddLog(LOGE,
9776 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009777 ret = -EINVAL;
9778 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 }
9780 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9781 }
9782
9783 if (probe_rsp_ie_len[1] > 0)
9784 {
9785 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9786 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309787 (tANI_U8*)&pBeacon->
9788 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 probe_rsp_ie_len[1], NULL,
9790 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9791 {
9792 hddLog(LOGE,
9793 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009794 ret = -EINVAL;
9795 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 }
9797 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9798 }
9799
9800 if (probe_rsp_ie_len[2] > 0)
9801 {
9802 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9803 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309804 (tANI_U8*)&pBeacon->
9805 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 probe_rsp_ie_len[2], NULL,
9807 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9808 {
9809 hddLog(LOGE,
9810 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009811 ret = -EINVAL;
9812 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 }
9814 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9815 }
9816
9817 if (probe_rsp_ie_len[1] == 0 )
9818 {
9819 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9820 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9821 eANI_BOOLEAN_FALSE) )
9822 {
9823 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009824 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 }
9826 }
9827
9828 if (probe_rsp_ie_len[2] == 0 )
9829 {
9830 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9831 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9832 eANI_BOOLEAN_FALSE) )
9833 {
9834 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009835 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009836 }
9837 }
9838
9839 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9840 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9841 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9842 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9843 == eHAL_STATUS_FAILURE)
9844 {
9845 hddLog(LOGE,
9846 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009847 ret = -EINVAL;
9848 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 }
9850 }
9851 else
9852 {
9853 // Reset WNI_CFG_PROBE_RSP Flags
9854 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9855
9856 hddLog(VOS_TRACE_LEVEL_INFO,
9857 "%s: No Probe Response IE received in set beacon",
9858 __func__);
9859 }
9860
9861 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309862 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 {
9864 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309865 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9866 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9868 {
9869 hddLog(LOGE,
9870 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009871 ret = -EINVAL;
9872 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 }
9874
9875 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9876 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9877 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9878 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9879 == eHAL_STATUS_FAILURE)
9880 {
9881 hddLog(LOGE,
9882 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009883 ret = -EINVAL;
9884 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 }
9886 }
9887 else
9888 {
9889 hddLog(VOS_TRACE_LEVEL_INFO,
9890 "%s: No Assoc Response IE received in set beacon",
9891 __func__);
9892
9893 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9894 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9895 eANI_BOOLEAN_FALSE) )
9896 {
9897 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009898 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 }
9900 }
9901
Jeff Johnsone7245742012-09-05 17:12:55 -07009902done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309904 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009905}
Jeff Johnson295189b2012-06-20 16:38:30 -07009906
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309907/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 * FUNCTION: wlan_hdd_validate_operation_channel
9909 * called by wlan_hdd_cfg80211_start_bss() and
9910 * wlan_hdd_cfg80211_set_channel()
9911 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309912 * channel list.
9913 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009914VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009915{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309916
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 v_U32_t num_ch = 0;
9918 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9919 u32 indx = 0;
9920 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309921 v_U8_t fValidChannel = FALSE, count = 0;
9922 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309923
Jeff Johnson295189b2012-06-20 16:38:30 -07009924 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9925
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309926 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309928 /* Validate the channel */
9929 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309931 if ( channel == rfChannels[count].channelNum )
9932 {
9933 fValidChannel = TRUE;
9934 break;
9935 }
9936 }
9937 if (fValidChannel != TRUE)
9938 {
9939 hddLog(VOS_TRACE_LEVEL_ERROR,
9940 "%s: Invalid Channel [%d]", __func__, channel);
9941 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 }
9943 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309944 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009945 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309946 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9947 valid_ch, &num_ch))
9948 {
9949 hddLog(VOS_TRACE_LEVEL_ERROR,
9950 "%s: failed to get valid channel list", __func__);
9951 return VOS_STATUS_E_FAILURE;
9952 }
9953 for (indx = 0; indx < num_ch; indx++)
9954 {
9955 if (channel == valid_ch[indx])
9956 {
9957 break;
9958 }
9959 }
9960
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309961 if (indx >= num_ch)
9962 {
9963 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9964 {
9965 eCsrBand band;
9966 unsigned int freq;
9967
9968 sme_GetFreqBand(hHal, &band);
9969
9970 if (eCSR_BAND_5G == band)
9971 {
9972#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9973 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9974 {
9975 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309976 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309977 }
9978 else
9979 {
9980 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309981 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309982 }
9983#else
9984 freq = ieee80211_channel_to_frequency(channel);
9985#endif
9986 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9987 return VOS_STATUS_SUCCESS;
9988 }
9989 }
9990
9991 hddLog(VOS_TRACE_LEVEL_ERROR,
9992 "%s: Invalid Channel [%d]", __func__, channel);
9993 return VOS_STATUS_E_FAILURE;
9994 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309996
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309998
Jeff Johnson295189b2012-06-20 16:38:30 -07009999}
10000
Viral Modi3a32cc52013-02-08 11:14:52 -080010001/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010002 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010003 * This function is used to set the channel number
10004 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010005static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010006 struct ieee80211_channel *chan,
10007 enum nl80211_channel_type channel_type
10008 )
10009{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010010 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010011 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010012 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010013 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010014 hdd_context_t *pHddCtx;
10015 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010016
10017 ENTER();
10018
10019 if( NULL == dev )
10020 {
10021 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010022 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010023 return -ENODEV;
10024 }
10025 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010026
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010027 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10028 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10029 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010030 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010031 "%s: device_mode = %s (%d) freq = %d", __func__,
10032 hdd_device_modetoString(pAdapter->device_mode),
10033 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010034
10035 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10036 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010037 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010038 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010039 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010040 }
10041
10042 /*
10043 * Do freq to chan conversion
10044 * TODO: for 11a
10045 */
10046
10047 channel = ieee80211_frequency_to_channel(freq);
10048
10049 /* Check freq range */
10050 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10051 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010054 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010055 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10056 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10057 return -EINVAL;
10058 }
10059
10060 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10061
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010062 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10063 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010064 {
10065 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10066 {
10067 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010068 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010069 return -EINVAL;
10070 }
10071 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10072 "%s: set channel to [%d] for device mode =%d",
10073 __func__, channel,pAdapter->device_mode);
10074 }
10075 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010076 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010077 )
10078 {
10079 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10080 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10081 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10082
10083 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10084 {
10085 /* Link is up then return cant set channel*/
10086 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010087 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010088 return -EINVAL;
10089 }
10090
10091 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10092 pHddStaCtx->conn_info.operationChannel = channel;
10093 pRoamProfile->ChannelInfo.ChannelList =
10094 &pHddStaCtx->conn_info.operationChannel;
10095 }
10096 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010097 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010098 )
10099 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010100 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10101 {
10102 if(VOS_STATUS_SUCCESS !=
10103 wlan_hdd_validate_operation_channel(pAdapter,channel))
10104 {
10105 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010106 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010107 return -EINVAL;
10108 }
10109 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10110 }
10111 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010112 {
10113 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10114
10115 /* If auto channel selection is configured as enable/ 1 then ignore
10116 channel set by supplicant
10117 */
10118 if ( cfg_param->apAutoChannelSelection )
10119 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010120 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10121 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010122 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010123 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10124 __func__, hdd_device_modetoString(pAdapter->device_mode),
10125 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010126 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010127 else
10128 {
10129 if(VOS_STATUS_SUCCESS !=
10130 wlan_hdd_validate_operation_channel(pAdapter,channel))
10131 {
10132 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010133 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010134 return -EINVAL;
10135 }
10136 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10137 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010138 }
10139 }
10140 else
10141 {
10142 hddLog(VOS_TRACE_LEVEL_FATAL,
10143 "%s: Invalid device mode failed to set valid channel", __func__);
10144 return -EINVAL;
10145 }
10146 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010147 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010148}
10149
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010150static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10151 struct net_device *dev,
10152 struct ieee80211_channel *chan,
10153 enum nl80211_channel_type channel_type
10154 )
10155{
10156 int ret;
10157
10158 vos_ssr_protect(__func__);
10159 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10160 vos_ssr_unprotect(__func__);
10161
10162 return ret;
10163}
10164
Anurag Chouhan83026002016-12-13 22:46:21 +053010165#ifdef DHCP_SERVER_OFFLOAD
10166void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10167 VOS_STATUS status)
10168{
10169 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10170
10171 ENTER();
10172
10173 if (NULL == adapter)
10174 {
10175 hddLog(VOS_TRACE_LEVEL_ERROR,
10176 "%s: adapter is NULL",__func__);
10177 return;
10178 }
10179
10180 adapter->dhcp_status.dhcp_offload_status = status;
10181 vos_event_set(&adapter->dhcp_status.vos_event);
10182 return;
10183}
10184
10185/**
10186 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10187 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010188 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010189 *
10190 * Return: None
10191 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010192VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10193 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010194{
10195 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10196 sir_dhcp_srv_offload_info dhcp_srv_info;
10197 tANI_U8 num_entries = 0;
10198 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10199 tANI_U8 num;
10200 tANI_U32 temp;
10201 VOS_STATUS ret;
10202
10203 ENTER();
10204
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010205 if (!re_init) {
10206 ret = wlan_hdd_validate_context(hdd_ctx);
10207 if (0 != ret)
10208 return VOS_STATUS_E_INVAL;
10209 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010210
10211 /* Prepare the request to send to SME */
10212 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10213 if (NULL == dhcp_srv_info) {
10214 hddLog(VOS_TRACE_LEVEL_ERROR,
10215 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10216 return VOS_STATUS_E_NOMEM;
10217 }
10218
10219 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10220
10221 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10222 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10223 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10224 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10225 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10226 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10227
10228 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10229 srv_ip,
10230 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010231 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010232 if (num_entries != IPADDR_NUM_ENTRIES) {
10233 hddLog(VOS_TRACE_LEVEL_ERROR,
10234 "%s: incorrect IP address (%s) assigned for DHCP server!",
10235 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10236 vos_mem_free(dhcp_srv_info);
10237 return VOS_STATUS_E_FAILURE;
10238 }
10239
10240 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10241 hddLog(VOS_TRACE_LEVEL_ERROR,
10242 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10243 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10244 vos_mem_free(dhcp_srv_info);
10245 return VOS_STATUS_E_FAILURE;
10246 }
10247
10248 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10249 hddLog(VOS_TRACE_LEVEL_ERROR,
10250 "%s: invalid IP address (%s)! The last field must be less than 100!",
10251 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10252 vos_mem_free(dhcp_srv_info);
10253 return VOS_STATUS_E_FAILURE;
10254 }
10255
10256 for (num = 0; num < num_entries; num++) {
10257 temp = srv_ip[num];
10258 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10259 }
10260
10261 if (eHAL_STATUS_SUCCESS !=
10262 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10263 hddLog(VOS_TRACE_LEVEL_ERROR,
10264 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10265 vos_mem_free(dhcp_srv_info);
10266 return VOS_STATUS_E_FAILURE;
10267 }
10268
10269 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10270 "%s: enable DHCP Server offload successfully!", __func__);
10271
10272 vos_mem_free(dhcp_srv_info);
10273 return 0;
10274}
10275#endif /* DHCP_SERVER_OFFLOAD */
10276
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010277/*
10278 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10279 * @wiphy_chan: wiphy channel number
10280 * @rfChannel: channel hw value
10281 * @disable: Disable/enable the flags
10282 *
10283 * Modify wiphy flags and cds state if channel is indoor.
10284 *
10285 * Return: void
10286 */
10287void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10288 v_U32_t rfChannel, bool disable)
10289{
10290 v_U32_t channelLoop;
10291 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10292
10293 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10294
10295 if (rfChannels[channelLoop].channelNum == rfChannel) {
10296 channelEnum = (eRfChannels)channelLoop;
10297 break;
10298 }
10299 }
10300
10301 if (INVALID_RF_CHANNEL == channelEnum)
10302 return;
10303
10304 if (disable) {
10305 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10306 wiphy_chan->flags |=
10307 IEEE80211_CHAN_DISABLED;
10308 regChannels[channelEnum].enabled =
10309 NV_CHANNEL_DISABLE;
10310 }
10311 } else {
10312 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10313 wiphy_chan->flags &=
10314 ~IEEE80211_CHAN_DISABLED;
10315 /*
10316 * Indoor channels are marked as DFS
10317 * during regulatory processing
10318 */
10319
10320 regChannels[channelEnum].enabled =
10321 NV_CHANNEL_DFS;
10322 }
10323 }
10324
10325}
10326
10327void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10328 bool disable)
10329{
10330 int band_num;
10331 int chan_num;
10332 v_U32_t rfChannel;
10333 struct ieee80211_channel *wiphy_chan;
10334 struct wiphy *wiphy;
10335
10336 ENTER();
10337 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10338
10339 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010340 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010341
10342 if (wiphy->bands[band_num] == NULL)
10343 continue;
10344
10345 for (chan_num = 0;
10346 chan_num < wiphy->bands[band_num]->n_channels;
10347 chan_num++) {
10348
10349 wiphy_chan =
10350 &(wiphy->bands[band_num]->channels[chan_num]);
10351 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10352
10353 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10354 disable);
10355 }
10356 }
10357 EXIT();
10358}
10359
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010360/*
10361 * FUNCTION: wlan_hdd_disconnect
10362 * This function is used to issue a disconnect request to SME
10363 */
10364int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10365{
10366 int status, result = 0;
10367 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10368 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10369 long ret;
10370 eConnectionState prev_conn_state;
10371 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10372
10373 ENTER();
10374
10375 status = wlan_hdd_validate_context(pHddCtx);
10376 if (0 != status)
10377 {
10378 return status;
10379 }
10380 /* Indicate sme of disconnect so that in progress connection or preauth
10381 * can be aborted
10382 */
10383 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10384 pAdapter->sessionId);
10385 pHddCtx->isAmpAllowed = VOS_TRUE;
10386
10387 /* Need to apply spin lock before decreasing active sessions
10388 * as there can be chance for double decrement if context switch
10389 * Calls hdd_DisConnectHandler.
10390 */
10391
10392 prev_conn_state = pHddStaCtx->conn_info.connState;
10393
10394 spin_lock_bh(&pAdapter->lock_for_active_session);
10395 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10396 {
10397 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10398 }
10399 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10400 spin_unlock_bh(&pAdapter->lock_for_active_session);
10401 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10402
10403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10404 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10405
10406 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10407
10408 /*
10409 * stop tx queues before deleting STA/BSS context from the firmware.
10410 * tx has to be disabled because the firmware can get busy dropping
10411 * the tx frames after BSS/STA has been deleted and will not send
10412 * back a response resulting in WDI timeout
10413 */
10414 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10415 netif_tx_disable(pAdapter->dev);
10416 netif_carrier_off(pAdapter->dev);
10417
10418 wlan_hdd_check_and_stop_mon(pAdapter, true);
10419
10420 /*issue disconnect*/
10421 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10422 pAdapter->sessionId, reason);
10423 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10424 prev_conn_state != eConnectionState_Connecting)
10425 {
10426 hddLog(LOG1,
10427 FL("status = %d, already disconnected"), status);
10428 result = 0;
10429 /*
10430 * Wait here instead of returning directly. This will block the
10431 * next connect command and allow processing of the disconnect
10432 * in SME else we might hit some race conditions leading to SME
10433 * and HDD out of sync. As disconnect is already in progress,
10434 * wait here for 1 sec instead of 5 sec.
10435 */
10436 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10437 goto wait_for_disconnect;
10438 }
10439 /*
10440 * Wait here instead of returning directly, this will block the next
10441 * connect command and allow processing of the scan for ssid and
10442 * the previous connect command in CSR. Else we might hit some
10443 * race conditions leading to SME and HDD out of sync.
10444 */
10445 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10446 {
10447 hddLog(LOG1,
10448 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10449 }
10450 else if ( 0 != status )
10451 {
10452 hddLog(LOGE,
10453 FL("csrRoamDisconnect failure, returned %d"),
10454 (int)status);
10455 result = -EINVAL;
10456 goto disconnected;
10457 }
10458wait_for_disconnect:
10459 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10460 msecs_to_jiffies(wait_time));
10461 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10462 {
10463 hddLog(LOGE,
10464 "%s: Failed to disconnect, timed out", __func__);
10465 result = -ETIMEDOUT;
10466 }
10467disconnected:
10468 hddLog(LOG1,
10469 FL("Set HDD connState to eConnectionState_NotConnected"));
10470 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10471#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10472 /* Sending disconnect event to userspace for kernel version < 3.11
10473 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10474 */
10475 hddLog(LOG1, FL("Send disconnected event to userspace"));
10476
10477 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10478 WLAN_REASON_UNSPECIFIED);
10479#endif
10480
10481 EXIT();
10482 return result;
10483}
10484
10485/*
10486 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10487 * on indoor channel
10488 * @hdd_ctx: pointer to hdd context
10489 *
10490 * STA should be disconnected before starting the SAP if it is on indoor
10491 * channel.
10492 *
10493 * Return: void
10494 */
10495void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10496{
10497
10498 hdd_adapter_t *sta_adapter;
10499 tANI_U8 sta_chan;
10500
10501 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10502
10503 if (!sta_chan) {
10504 hddLog(LOG1, FL("STA not connected"));
10505 return;
10506 }
10507
10508 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10509
10510 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10511 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10512 sta_chan);
10513 return;
10514 }
10515
10516 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10517
10518 if (!sta_adapter) {
10519 hddLog(LOG1, FL("STA adapter doesn't exist"));
10520 return;
10521 }
10522
10523 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10524 /* Issue Disconnect request */
10525 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10526}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010527
Jeff Johnson295189b2012-06-20 16:38:30 -070010528#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10529static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10530 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010531#else
10532static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10533 struct cfg80211_beacon_data *params,
10534 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010535 enum nl80211_hidden_ssid hidden_ssid,
10536 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010537#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010538{
10539 tsap_Config_t *pConfig;
10540 beacon_data_t *pBeacon = NULL;
10541 struct ieee80211_mgmt *pMgmt_frame;
10542 v_U8_t *pIe=NULL;
10543 v_U16_t capab_info;
10544 eCsrAuthType RSNAuthType;
10545 eCsrEncryptionType RSNEncryptType;
10546 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010547 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 tpWLAN_SAPEventCB pSapEventCallback;
10549 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010551 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010553 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010555 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010556 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010557 v_BOOL_t MFPCapable = VOS_FALSE;
10558 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010559 v_BOOL_t sapEnable11AC =
10560 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010561 u_int16_t prev_rsn_length = 0;
10562
Jeff Johnson295189b2012-06-20 16:38:30 -070010563 ENTER();
10564
Nitesh Shah9b066282017-06-06 18:05:52 +053010565 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010566 iniConfig = pHddCtx->cfg_ini;
10567
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010568 /* Mark the indoor channel (passive) to disable */
10569 if (iniConfig->disable_indoor_channel) {
10570 hdd_update_indoor_channel(pHddCtx, true);
10571
10572 if (!VOS_IS_STATUS_SUCCESS(
10573 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10574 hdd_update_indoor_channel(pHddCtx, false);
10575 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10576 FL("Can't start BSS: update channel list failed"));
10577 return eHAL_STATUS_FAILURE;
10578 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010579
10580 /* check if STA is on indoor channel */
10581 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10582 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010583 }
10584
Jeff Johnson295189b2012-06-20 16:38:30 -070010585 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10586
10587 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10588
10589 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10590
10591 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10592
10593 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10594
10595 //channel is already set in the set_channel Call back
10596 //pConfig->channel = pCommitConfig->channel;
10597
10598 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010599 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10601
10602 pConfig->dtim_period = pBeacon->dtim_period;
10603
Arif Hussain6d2a3322013-11-17 19:50:10 -080010604 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010605 pConfig->dtim_period);
10606
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010607 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010608 {
10609 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010611 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10612 {
10613 tANI_BOOLEAN restartNeeded;
10614 pConfig->ieee80211d = 1;
10615 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10616 sme_setRegInfo(hHal, pConfig->countryCode);
10617 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10618 }
10619 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010621 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010622 pConfig->ieee80211d = 1;
10623 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10624 sme_setRegInfo(hHal, pConfig->countryCode);
10625 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010626 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010627 else
10628 {
10629 pConfig->ieee80211d = 0;
10630 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010631 /*
10632 * If auto channel is configured i.e. channel is 0,
10633 * so skip channel validation.
10634 */
10635 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10636 {
10637 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10638 {
10639 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010640 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010641 return -EINVAL;
10642 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010643 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010644 }
10645 else
10646 {
10647 if(1 != pHddCtx->is_dynamic_channel_range_set)
10648 {
10649 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10650 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10651 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10652 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010653 pHddCtx->is_dynamic_channel_range_set = 0;
10654 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010655 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010656 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010657 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010658 {
10659 pConfig->ieee80211d = 0;
10660 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010661
10662#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10663 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10664 pConfig->authType = eSAP_OPEN_SYSTEM;
10665 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10666 pConfig->authType = eSAP_SHARED_KEY;
10667 else
10668 pConfig->authType = eSAP_AUTO_SWITCH;
10669#else
10670 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10671 pConfig->authType = eSAP_OPEN_SYSTEM;
10672 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10673 pConfig->authType = eSAP_SHARED_KEY;
10674 else
10675 pConfig->authType = eSAP_AUTO_SWITCH;
10676#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010677
10678 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010679
10680 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010682#ifdef SAP_AUTH_OFFLOAD
10683 /* In case of sap offload, hostapd.conf is configuted with open mode and
10684 * security is configured from ini file. Due to open mode in hostapd.conf
10685 * privacy bit is set to false which will result in not sending,
10686 * data packets as encrypted.
10687 * If enable_sap_auth_offload is enabled in ini and
10688 * sap_auth_offload_sec_type is type of WPA2-PSK,
10689 * driver will set privacy bit to 1.
10690 */
10691 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10692 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10693 pConfig->privacy = VOS_TRUE;
10694#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010695
10696 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10697
10698 /*Set wps station to configured*/
10699 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10700
10701 if(pIe)
10702 {
10703 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10704 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010705 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 return -EINVAL;
10707 }
10708 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10709 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010710 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010711 /* Check 15 bit of WPS IE as it contain information for wps state
10712 * WPS state
10713 */
10714 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10715 {
10716 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10717 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10718 {
10719 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10720 }
10721 }
10722 }
10723 else
10724 {
10725 pConfig->wps_state = SAP_WPS_DISABLED;
10726 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010727 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010728
c_hpothufe599e92014-06-16 11:38:55 +053010729 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10730 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10731 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10732 eCSR_ENCRYPT_TYPE_NONE;
10733
Jeff Johnson295189b2012-06-20 16:38:30 -070010734 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010735 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010736 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010737 WLAN_EID_RSN);
10738 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010739 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010740 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010741 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10742 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10743 pConfig->RSNWPAReqIELength);
10744 else
10745 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10746 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010747 /* The actual processing may eventually be more extensive than
10748 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010749 * by the app.
10750 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010751 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010752 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10753 &RSNEncryptType,
10754 &mcRSNEncryptType,
10755 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010756 &MFPCapable,
10757 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010758 pConfig->RSNWPAReqIE[1]+2,
10759 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010760
10761 if( VOS_STATUS_SUCCESS == status )
10762 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010763 /* Now copy over all the security attributes you have
10764 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010765 * */
10766 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10767 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10768 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10769 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010770 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010771 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010772 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10773 }
10774 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010775
Jeff Johnson295189b2012-06-20 16:38:30 -070010776 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10777 pBeacon->tail, pBeacon->tail_len);
10778
10779 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10780 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010781 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 {
10783 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010784 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010785 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010786 if (pConfig->RSNWPAReqIELength <=
10787 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10788 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10789 pIe[1] + 2);
10790 else
10791 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10792 pConfig->RSNWPAReqIELength);
10793
Jeff Johnson295189b2012-06-20 16:38:30 -070010794 }
10795 else
10796 {
10797 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010798 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10799 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10800 pConfig->RSNWPAReqIELength);
10801 else
10802 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10803 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010804 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10806 &RSNEncryptType,
10807 &mcRSNEncryptType,
10808 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010809 &MFPCapable,
10810 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010811 pConfig->RSNWPAReqIE[1]+2,
10812 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010813
10814 if( VOS_STATUS_SUCCESS == status )
10815 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010816 /* Now copy over all the security attributes you have
10817 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 * */
10819 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10820 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10821 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10822 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010823 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010824 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10826 }
10827 }
10828 }
10829
Kapil Gupta137ef892016-12-13 19:38:00 +053010830 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010831 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10832 return -EINVAL;
10833 }
10834
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10836
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010837#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010838 if (params->ssid != NULL)
10839 {
10840 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10841 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10842 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10843 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10844 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010845#else
10846 if (ssid != NULL)
10847 {
10848 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10849 pConfig->SSIDinfo.ssid.length = ssid_len;
10850 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10851 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10852 }
10853#endif
10854
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010857
Jeff Johnson295189b2012-06-20 16:38:30 -070010858 /* default value */
10859 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10860 pConfig->num_accept_mac = 0;
10861 pConfig->num_deny_mac = 0;
10862
10863 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10864 pBeacon->tail, pBeacon->tail_len);
10865
10866 /* pIe for black list is following form:
10867 type : 1 byte
10868 length : 1 byte
10869 OUI : 4 bytes
10870 acl type : 1 byte
10871 no of mac addr in black list: 1 byte
10872 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010873 */
10874 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 {
10876 pConfig->SapMacaddr_acl = pIe[6];
10877 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010878 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010880 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10881 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10883 for (i = 0; i < pConfig->num_deny_mac; i++)
10884 {
10885 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10886 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010887 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010888 }
10889 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10890 pBeacon->tail, pBeacon->tail_len);
10891
10892 /* pIe for white list is following form:
10893 type : 1 byte
10894 length : 1 byte
10895 OUI : 4 bytes
10896 acl type : 1 byte
10897 no of mac addr in white list: 1 byte
10898 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010899 */
10900 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010901 {
10902 pConfig->SapMacaddr_acl = pIe[6];
10903 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010904 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010906 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10907 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010908 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10909 for (i = 0; i < pConfig->num_accept_mac; i++)
10910 {
10911 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10912 acl_entry++;
10913 }
10914 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010915
Jeff Johnson295189b2012-06-20 16:38:30 -070010916 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10917
Jeff Johnsone7245742012-09-05 17:12:55 -070010918#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010919 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010920 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10921 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010922 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10923 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010924 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10925 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010926 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10927 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010928 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010929 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010930 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010931 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010932
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010933 /* If ACS disable and selected channel <= 14
10934 * OR
10935 * ACS enabled and ACS operating band is choosen as 2.4
10936 * AND
10937 * VHT in 2.4G Disabled
10938 * THEN
10939 * Fallback to 11N mode
10940 */
10941 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10942 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010943 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010944 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010945 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010946 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10947 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010948 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10949 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010950 }
10951#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010952
Jeff Johnson295189b2012-06-20 16:38:30 -070010953 // ht_capab is not what the name conveys,this is used for protection bitmap
10954 pConfig->ht_capab =
10955 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10956
Kapil Gupta137ef892016-12-13 19:38:00 +053010957 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 {
10959 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10960 return -EINVAL;
10961 }
10962
10963 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010964 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010965 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10966 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010967 pConfig->obssProtEnabled =
10968 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010969
Chet Lanctot8cecea22014-02-11 19:09:36 -080010970#ifdef WLAN_FEATURE_11W
10971 pConfig->mfpCapable = MFPCapable;
10972 pConfig->mfpRequired = MFPRequired;
10973 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10974 pConfig->mfpCapable, pConfig->mfpRequired);
10975#endif
10976
Arif Hussain6d2a3322013-11-17 19:50:10 -080010977 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010979 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10980 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10981 (int)pConfig->channel);
10982 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10983 pConfig->SapHw_mode, pConfig->privacy,
10984 pConfig->authType);
10985 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10986 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10987 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10988 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010989
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010990 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 {
10992 //Bss already started. just return.
10993 //TODO Probably it should update some beacon params.
10994 hddLog( LOGE, "Bss Already started...Ignore the request");
10995 EXIT();
10996 return 0;
10997 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010998
Agarwal Ashish51325b52014-06-16 16:50:49 +053010999 if (vos_max_concurrent_connections_reached()) {
11000 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11001 return -EINVAL;
11002 }
11003
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 pConfig->persona = pHostapdAdapter->device_mode;
11005
Peng Xu2446a892014-09-05 17:21:18 +053011006 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11007 if ( NULL != psmeConfig)
11008 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011009 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011010 sme_GetConfigParam(hHal, psmeConfig);
11011 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011012#ifdef WLAN_FEATURE_AP_HT40_24G
11013 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11014 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11015 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11016 {
11017 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11018 sme_UpdateConfig (hHal, psmeConfig);
11019 }
11020#endif
Peng Xu2446a892014-09-05 17:21:18 +053011021 vos_mem_free(psmeConfig);
11022 }
Peng Xuafc34e32014-09-25 13:23:55 +053011023 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011024
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011025 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11026
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 pSapEventCallback = hdd_hostapd_SAPEventCB;
11028 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11029 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11030 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011031 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011032 ret = -EINVAL;
11033 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 }
11035
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011036 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011037 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11038
11039 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011040
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011042 {
11043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011044 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011045 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 VOS_ASSERT(0);
11047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011048
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011050 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11051 VOS_STATUS_SUCCESS)
11052 {
11053 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11054 VOS_ASSERT(0);
11055 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011056 /* Initialize WMM configuation */
11057 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011058 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011059
Anurag Chouhan83026002016-12-13 22:46:21 +053011060#ifdef DHCP_SERVER_OFFLOAD
11061 /* set dhcp server offload */
11062 if (iniConfig->enable_dhcp_srv_offload &&
11063 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011064 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011065 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011066 if (!VOS_IS_STATUS_SUCCESS(status))
11067 {
11068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11069 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011070 vos_event_reset(&pHostapdState->vosEvent);
11071 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11072 status = vos_wait_single_event(&pHostapdState->vosEvent,
11073 10000);
11074 if (!VOS_IS_STATUS_SUCCESS(status)) {
11075 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011076 ret = -EINVAL;
11077 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011078 }
11079 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011080 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011081 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11082 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11083 {
11084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11085 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11086 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011087 vos_event_reset(&pHostapdState->vosEvent);
11088 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11089 status = vos_wait_single_event(&pHostapdState->vosEvent,
11090 10000);
11091 if (!VOS_IS_STATUS_SUCCESS(status)) {
11092 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011093 ret = -EINVAL;
11094 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011095 }
11096 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011097 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011098#ifdef MDNS_OFFLOAD
11099 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011100 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011101 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11102 if (VOS_IS_STATUS_SUCCESS(status))
11103 {
11104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11105 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011106 vos_event_reset(&pHostapdState->vosEvent);
11107 if (VOS_STATUS_SUCCESS ==
11108 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11109 status = vos_wait_single_event(&pHostapdState->vosEvent,
11110 10000);
11111 if (!VOS_IS_STATUS_SUCCESS(status)) {
11112 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011113 ret = -EINVAL;
11114 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011115 }
11116 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011117 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011118 status = vos_wait_single_event(&pHostapdAdapter->
11119 mdns_status.vos_event, 2000);
11120 if (!VOS_IS_STATUS_SUCCESS(status) ||
11121 pHostapdAdapter->mdns_status.mdns_enable_status ||
11122 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11123 pHostapdAdapter->mdns_status.mdns_resp_status)
11124 {
11125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11126 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11127 pHostapdAdapter->mdns_status.mdns_enable_status,
11128 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11129 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011130 vos_event_reset(&pHostapdState->vosEvent);
11131 if (VOS_STATUS_SUCCESS ==
11132 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11133 status = vos_wait_single_event(&pHostapdState->vosEvent,
11134 10000);
11135 if (!VOS_IS_STATUS_SUCCESS(status)) {
11136 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011137 ret = -EINVAL;
11138 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011139 }
11140 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011141 }
11142 }
11143#endif /* MDNS_OFFLOAD */
11144 } else {
11145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11146 ("DHCP Disabled ini %d, FW %d"),
11147 iniConfig->enable_dhcp_srv_offload,
11148 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011149 }
11150#endif /* DHCP_SERVER_OFFLOAD */
11151
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011152#ifdef WLAN_FEATURE_P2P_DEBUG
11153 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11154 {
11155 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11156 {
11157 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11158 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011159 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011160 }
11161 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11162 {
11163 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11164 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011165 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011166 }
11167 }
11168#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011169 /* Check and restart SAP if it is on Unsafe channel */
11170 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011171
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 pHostapdState->bCommit = TRUE;
11173 EXIT();
11174
11175 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011176error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011177 /* Revert the indoor to passive marking if START BSS fails */
11178 if (iniConfig->disable_indoor_channel) {
11179 hdd_update_indoor_channel(pHddCtx, false);
11180 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11181 }
11182
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011183 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11184 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011185}
11186
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011187#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011188static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011189 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 struct beacon_parameters *params)
11191{
11192 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011193 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011194 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011195
11196 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011197
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011198 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11199 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11200 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011201 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11202 hdd_device_modetoString(pAdapter->device_mode),
11203 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011204
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11206 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011207 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011208 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011209 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011210 }
11211
Agarwal Ashish51325b52014-06-16 16:50:49 +053011212 if (vos_max_concurrent_connections_reached()) {
11213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11214 return -EINVAL;
11215 }
11216
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011217 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011219 )
11220 {
11221 beacon_data_t *old,*new;
11222
11223 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011226 {
11227 hddLog(VOS_TRACE_LEVEL_WARN,
11228 FL("already beacon info added to session(%d)"),
11229 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011231 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
11233 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11234
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011235 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011236 {
11237 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011238 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 return -EINVAL;
11240 }
11241
11242 pAdapter->sessionCtx.ap.beacon = new;
11243
11244 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11245 }
11246
11247 EXIT();
11248 return status;
11249}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011250
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011251static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11252 struct net_device *dev,
11253 struct beacon_parameters *params)
11254{
11255 int ret;
11256
11257 vos_ssr_protect(__func__);
11258 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11259 vos_ssr_unprotect(__func__);
11260
11261 return ret;
11262}
11263
11264static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 struct net_device *dev,
11266 struct beacon_parameters *params)
11267{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011269 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11270 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011271 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011272
11273 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011274
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11276 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11277 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11278 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11279 __func__, hdd_device_modetoString(pAdapter->device_mode),
11280 pAdapter->device_mode);
11281
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11283 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011284 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011285 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011286 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011287 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011288
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011289 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011290 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011291 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 {
11293 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011294
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011298 {
11299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11300 FL("session(%d) old and new heads points to NULL"),
11301 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011303 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011304
11305 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11306
11307 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011308 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011309 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 return -EINVAL;
11311 }
11312
11313 pAdapter->sessionCtx.ap.beacon = new;
11314
11315 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11316 }
11317
11318 EXIT();
11319 return status;
11320}
11321
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011322static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11323 struct net_device *dev,
11324 struct beacon_parameters *params)
11325{
11326 int ret;
11327
11328 vos_ssr_protect(__func__);
11329 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11330 vos_ssr_unprotect(__func__);
11331
11332 return ret;
11333}
11334
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011335#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11336
11337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011338static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011340#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011341static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011342 struct net_device *dev)
11343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011344{
11345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011346 hdd_context_t *pHddCtx = NULL;
11347 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011348 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011349 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011350
11351 ENTER();
11352
11353 if (NULL == pAdapter)
11354 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011356 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 return -ENODEV;
11358 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011359
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011360 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11361 TRACE_CODE_HDD_CFG80211_STOP_AP,
11362 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11364 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011365 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011366 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011367 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011368 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011369
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011370 pScanInfo = &pHddCtx->scan_info;
11371
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011372 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11373 __func__, hdd_device_modetoString(pAdapter->device_mode),
11374 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011375
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011376 ret = wlan_hdd_scan_abort(pAdapter);
11377
Girish Gowli4bf7a632014-06-12 13:42:11 +053011378 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011379 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11381 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011382
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011383 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011384 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11386 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011387
Jeff Johnsone7245742012-09-05 17:12:55 -070011388 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011389 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011390 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011391 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011392 }
11393
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011394 /* Delete all associated STAs before stopping AP/P2P GO */
11395 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011396 hdd_hostapd_stop(dev);
11397
Jeff Johnson295189b2012-06-20 16:38:30 -070011398 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 )
11401 {
11402 beacon_data_t *old;
11403
11404 old = pAdapter->sessionCtx.ap.beacon;
11405
11406 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011407 {
11408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11409 FL("session(%d) beacon data points to NULL"),
11410 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011412 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011413
Jeff Johnson295189b2012-06-20 16:38:30 -070011414 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011415
11416 mutex_lock(&pHddCtx->sap_lock);
11417 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11418 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011419 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011420 {
11421 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11422
11423 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11424
11425 if (!VOS_IS_STATUS_SUCCESS(status))
11426 {
11427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011428 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011429 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011430 }
11431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011433 /* BSS stopped, clear the active sessions for this device mode */
11434 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 }
11436 mutex_unlock(&pHddCtx->sap_lock);
11437
11438 if(status != VOS_STATUS_SUCCESS)
11439 {
11440 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011441 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 return -EINVAL;
11443 }
11444
Jeff Johnson4416a782013-03-25 14:17:50 -070011445 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11447 ==eHAL_STATUS_FAILURE)
11448 {
11449 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011450 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 }
11452
Jeff Johnson4416a782013-03-25 14:17:50 -070011453 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11455 eANI_BOOLEAN_FALSE) )
11456 {
11457 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011458 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011459 }
11460
11461 // Reset WNI_CFG_PROBE_RSP Flags
11462 wlan_hdd_reset_prob_rspies(pAdapter);
11463
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011464 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11465
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 pAdapter->sessionCtx.ap.beacon = NULL;
11467 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011468#ifdef WLAN_FEATURE_P2P_DEBUG
11469 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11470 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11471 {
11472 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11473 "GO got removed");
11474 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11475 }
11476#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 }
11478 EXIT();
11479 return status;
11480}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011481
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011482#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11483static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11484 struct net_device *dev)
11485{
11486 int ret;
11487
11488 vos_ssr_protect(__func__);
11489 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11490 vos_ssr_unprotect(__func__);
11491
11492 return ret;
11493}
11494#else
11495static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11496 struct net_device *dev)
11497{
11498 int ret;
11499
11500 vos_ssr_protect(__func__);
11501 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11502 vos_ssr_unprotect(__func__);
11503
11504 return ret;
11505}
11506#endif
11507
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011508#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11509
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011510static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011511 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011512 struct cfg80211_ap_settings *params)
11513{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011514 hdd_adapter_t *pAdapter;
11515 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011516 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011517
11518 ENTER();
11519
Girish Gowlib143d7a2015-02-18 19:39:55 +053011520 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011521 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011523 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011524 return -ENODEV;
11525 }
11526
11527 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11528 if (NULL == pAdapter)
11529 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011531 "%s: HDD adapter is Null", __func__);
11532 return -ENODEV;
11533 }
11534
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011535 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11536 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11537 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011538 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11539 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011541 "%s: HDD adapter magic is invalid", __func__);
11542 return -ENODEV;
11543 }
11544
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011545 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11546
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011547 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011548 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011549 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011550 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011551 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011552 }
11553
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011554 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11555 __func__, hdd_device_modetoString(pAdapter->device_mode),
11556 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011557
11558 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011559 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011560 )
11561 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011562 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011563
11564 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011565
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011566 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011567 {
11568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11569 FL("already beacon info added to session(%d)"),
11570 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011571 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011572 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011573
Girish Gowlib143d7a2015-02-18 19:39:55 +053011574#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11575 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11576 &new,
11577 &params->beacon);
11578#else
11579 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11580 &new,
11581 &params->beacon,
11582 params->dtim_period);
11583#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011584
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011585 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011586 {
11587 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011588 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011589 return -EINVAL;
11590 }
11591 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011593 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11594#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11595 params->channel, params->channel_type);
11596#else
11597 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11598#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011599#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011600 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011601 params->ssid_len, params->hidden_ssid,
11602 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011603 }
11604
11605 EXIT();
11606 return status;
11607}
11608
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011609static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11610 struct net_device *dev,
11611 struct cfg80211_ap_settings *params)
11612{
11613 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011614
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011615 vos_ssr_protect(__func__);
11616 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11617 vos_ssr_unprotect(__func__);
11618
11619 return ret;
11620}
11621
11622static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011623 struct net_device *dev,
11624 struct cfg80211_beacon_data *params)
11625{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011627 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011628 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011629
11630 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011631
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11633 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11634 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011635 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011636 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011637
11638 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11639 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011640 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011641 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011643 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011644
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011645 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011646 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011648 {
11649 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011650
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011651 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011652
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011653 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011654 {
11655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11656 FL("session(%d) beacon data points to NULL"),
11657 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011658 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011659 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011660
11661 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11662
11663 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011664 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011665 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011666 return -EINVAL;
11667 }
11668
11669 pAdapter->sessionCtx.ap.beacon = new;
11670
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011671 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11672 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011673 }
11674
11675 EXIT();
11676 return status;
11677}
11678
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011679static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11680 struct net_device *dev,
11681 struct cfg80211_beacon_data *params)
11682{
11683 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011684
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011685 vos_ssr_protect(__func__);
11686 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11687 vos_ssr_unprotect(__func__);
11688
11689 return ret;
11690}
11691
11692#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011693
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011694static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 struct net_device *dev,
11696 struct bss_parameters *params)
11697{
11698 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011699 hdd_context_t *pHddCtx;
11700 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011701
11702 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011703
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011704 if (NULL == pAdapter)
11705 {
11706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11707 "%s: HDD adapter is Null", __func__);
11708 return -ENODEV;
11709 }
11710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011711 ret = wlan_hdd_validate_context(pHddCtx);
11712 if (0 != ret)
11713 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011714 return ret;
11715 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011716 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11717 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11718 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011719 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11720 __func__, hdd_device_modetoString(pAdapter->device_mode),
11721 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011722
11723 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011725 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 {
11727 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11728 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011729 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 {
11731 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 }
11734
11735 EXIT();
11736 return 0;
11737}
11738
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011739static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11740 struct net_device *dev,
11741 struct bss_parameters *params)
11742{
11743 int ret;
11744
11745 vos_ssr_protect(__func__);
11746 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11747 vos_ssr_unprotect(__func__);
11748
11749 return ret;
11750}
Kiet Lam10841362013-11-01 11:36:50 +053011751/* FUNCTION: wlan_hdd_change_country_code_cd
11752* to wait for contry code completion
11753*/
11754void* wlan_hdd_change_country_code_cb(void *pAdapter)
11755{
11756 hdd_adapter_t *call_back_pAdapter = pAdapter;
11757 complete(&call_back_pAdapter->change_country_code);
11758 return NULL;
11759}
11760
Jeff Johnson295189b2012-06-20 16:38:30 -070011761/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011762 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11764 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011765int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 struct net_device *ndev,
11767 enum nl80211_iftype type,
11768 u32 *flags,
11769 struct vif_params *params
11770 )
11771{
11772 struct wireless_dev *wdev;
11773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011774 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011775 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 tCsrRoamProfile *pRoamProfile = NULL;
11777 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011778 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 eMib_dot11DesiredBssType connectedBssType;
11780 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011781 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011782
11783 ENTER();
11784
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011785 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011786 {
11787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11788 "%s: Adapter context is null", __func__);
11789 return VOS_STATUS_E_FAILURE;
11790 }
11791
11792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11793 if (!pHddCtx)
11794 {
11795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11796 "%s: HDD context is null", __func__);
11797 return VOS_STATUS_E_FAILURE;
11798 }
11799
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011800 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11801 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11802 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011804 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011806 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011807 }
11808
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11810 __func__, hdd_device_modetoString(pAdapter->device_mode),
11811 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011812
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011813 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11814 hddLog(VOS_TRACE_LEVEL_FATAL,
11815 "%s: STA + MON is in progress, cannot change interface",
11816 __func__);
11817 }
11818
Agarwal Ashish51325b52014-06-16 16:50:49 +053011819 if (vos_max_concurrent_connections_reached()) {
11820 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11821 return -EINVAL;
11822 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011823 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 wdev = ndev->ieee80211_ptr;
11825
11826#ifdef WLAN_BTAMP_FEATURE
11827 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11828 (NL80211_IFTYPE_ADHOC == type)||
11829 (NL80211_IFTYPE_AP == type)||
11830 (NL80211_IFTYPE_P2P_GO == type))
11831 {
11832 pHddCtx->isAmpAllowed = VOS_FALSE;
11833 // stop AMP traffic
11834 status = WLANBAP_StopAmp();
11835 if(VOS_STATUS_SUCCESS != status )
11836 {
11837 pHddCtx->isAmpAllowed = VOS_TRUE;
11838 hddLog(VOS_TRACE_LEVEL_FATAL,
11839 "%s: Failed to stop AMP", __func__);
11840 return -EINVAL;
11841 }
11842 }
11843#endif //WLAN_BTAMP_FEATURE
11844 /* Reset the current device mode bit mask*/
11845 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11846
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011847 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11848 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11849 (type == NL80211_IFTYPE_P2P_GO)))
11850 {
11851 /* Notify Mode change in case of concurrency.
11852 * Below function invokes TDLS teardown Functionality Since TDLS is
11853 * not Supported in case of concurrency i.e Once P2P session
11854 * is detected disable offchannel and teardown TDLS links
11855 */
11856 hddLog(LOG1,
11857 FL("Device mode = %d Interface type = %d"),
11858 pAdapter->device_mode, type);
11859 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11860 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011861
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011863 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011864 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 )
11866 {
11867 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011868 if (!pWextState)
11869 {
11870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11871 "%s: pWextState is null", __func__);
11872 return VOS_STATUS_E_FAILURE;
11873 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 pRoamProfile = &pWextState->roamProfile;
11875 LastBSSType = pRoamProfile->BSSType;
11876
11877 switch (type)
11878 {
11879 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 hddLog(VOS_TRACE_LEVEL_INFO,
11882 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11883 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011884#ifdef WLAN_FEATURE_11AC
11885 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11886 {
11887 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11888 }
11889#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011890 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011891 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011892 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011893 //Check for sub-string p2p to confirm its a p2p interface
11894 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011895 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011896#ifdef FEATURE_WLAN_TDLS
11897 mutex_lock(&pHddCtx->tdls_lock);
11898 wlan_hdd_tdls_exit(pAdapter, TRUE);
11899 mutex_unlock(&pHddCtx->tdls_lock);
11900#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011901 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11902 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11903 }
11904 else
11905 {
11906 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011907 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011908 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011910
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 case NL80211_IFTYPE_ADHOC:
11912 hddLog(VOS_TRACE_LEVEL_INFO,
11913 "%s: setting interface Type to ADHOC", __func__);
11914 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11915 pRoamProfile->phyMode =
11916 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011917 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011918 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011919 hdd_set_ibss_ops( pAdapter );
11920 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011921
11922 status = hdd_sta_id_hash_attach(pAdapter);
11923 if (VOS_STATUS_SUCCESS != status) {
11924 hddLog(VOS_TRACE_LEVEL_ERROR,
11925 FL("Failed to initialize hash for IBSS"));
11926 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 break;
11928
11929 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011930 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011931 {
11932 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11933 "%s: setting interface Type to %s", __func__,
11934 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11935
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011936 //Cancel any remain on channel for GO mode
11937 if (NL80211_IFTYPE_P2P_GO == type)
11938 {
11939 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11940 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011941 if (NL80211_IFTYPE_AP == type)
11942 {
11943 /* As Loading WLAN Driver one interface being created for p2p device
11944 * address. This will take one HW STA and the max number of clients
11945 * that can connect to softAP will be reduced by one. so while changing
11946 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11947 * interface as it is not required in SoftAP mode.
11948 */
11949
11950 // Get P2P Adapter
11951 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11952
11953 if (pP2pAdapter)
11954 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011955 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011956 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011957 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11958 }
11959 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011960 //Disable IMPS & BMPS for SAP/GO
11961 if(VOS_STATUS_E_FAILURE ==
11962 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11963 {
11964 //Fail to Exit BMPS
11965 VOS_ASSERT(0);
11966 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011967
11968 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11969
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011970#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011971
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011972 /* A Mutex Lock is introduced while changing the mode to
11973 * protect the concurrent access for the Adapters by TDLS
11974 * module.
11975 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011976 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011977#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011979 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011980 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11982 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011983#ifdef FEATURE_WLAN_TDLS
11984 mutex_unlock(&pHddCtx->tdls_lock);
11985#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011986 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11987 (pConfig->apRandomBssidEnabled))
11988 {
11989 /* To meet Android requirements create a randomized
11990 MAC address of the form 02:1A:11:Fx:xx:xx */
11991 get_random_bytes(&ndev->dev_addr[3], 3);
11992 ndev->dev_addr[0] = 0x02;
11993 ndev->dev_addr[1] = 0x1A;
11994 ndev->dev_addr[2] = 0x11;
11995 ndev->dev_addr[3] |= 0xF0;
11996 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11997 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011998 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11999 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012000 }
12001
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 hdd_set_ap_ops( pAdapter->dev );
12003
Kiet Lam10841362013-11-01 11:36:50 +053012004 /* This is for only SAP mode where users can
12005 * control country through ini.
12006 * P2P GO follows station country code
12007 * acquired during the STA scanning. */
12008 if((NL80211_IFTYPE_AP == type) &&
12009 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12010 {
12011 int status = 0;
12012 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12013 "%s: setting country code from INI ", __func__);
12014 init_completion(&pAdapter->change_country_code);
12015 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12016 (void *)(tSmeChangeCountryCallback)
12017 wlan_hdd_change_country_code_cb,
12018 pConfig->apCntryCode, pAdapter,
12019 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012020 eSIR_FALSE,
12021 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012022 if (eHAL_STATUS_SUCCESS == status)
12023 {
12024 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012025 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012026 &pAdapter->change_country_code,
12027 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012028 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012029 {
12030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012031 FL("SME Timed out while setting country code %ld"),
12032 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012033
12034 if (pHddCtx->isLogpInProgress)
12035 {
12036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12037 "%s: LOGP in Progress. Ignore!!!", __func__);
12038 return -EAGAIN;
12039 }
Kiet Lam10841362013-11-01 11:36:50 +053012040 }
12041 }
12042 else
12043 {
12044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012045 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012046 return -EINVAL;
12047 }
12048 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012049 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 if(status != VOS_STATUS_SUCCESS)
12051 {
12052 hddLog(VOS_TRACE_LEVEL_FATAL,
12053 "%s: Error initializing the ap mode", __func__);
12054 return -EINVAL;
12055 }
12056 hdd_set_conparam(1);
12057
Nirav Shah7e3c8132015-06-22 23:51:42 +053012058 status = hdd_sta_id_hash_attach(pAdapter);
12059 if (VOS_STATUS_SUCCESS != status)
12060 {
12061 hddLog(VOS_TRACE_LEVEL_ERROR,
12062 FL("Failed to initialize hash for AP"));
12063 return -EINVAL;
12064 }
12065
Jeff Johnson295189b2012-06-20 16:38:30 -070012066 /*interface type changed update in wiphy structure*/
12067 if(wdev)
12068 {
12069 wdev->iftype = type;
12070 pHddCtx->change_iface = type;
12071 }
12072 else
12073 {
12074 hddLog(VOS_TRACE_LEVEL_ERROR,
12075 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12076 return -EINVAL;
12077 }
12078 goto done;
12079 }
12080
12081 default:
12082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12083 __func__);
12084 return -EOPNOTSUPP;
12085 }
12086 }
12087 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012089 )
12090 {
12091 switch(type)
12092 {
12093 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012094 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012095 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012096
12097 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012098#ifdef FEATURE_WLAN_TDLS
12099
12100 /* A Mutex Lock is introduced while changing the mode to
12101 * protect the concurrent access for the Adapters by TDLS
12102 * module.
12103 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012104 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012105#endif
c_hpothu002231a2015-02-05 14:58:51 +053012106 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012108 //Check for sub-string p2p to confirm its a p2p interface
12109 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012110 {
12111 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12112 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12113 }
12114 else
12115 {
12116 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012118 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012119
12120 /* set con_mode to STA only when no SAP concurrency mode */
12121 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12122 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012123 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012124 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12125 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012126#ifdef FEATURE_WLAN_TDLS
12127 mutex_unlock(&pHddCtx->tdls_lock);
12128#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012129 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 if( VOS_STATUS_SUCCESS != status )
12131 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012132 /* In case of JB, for P2P-GO, only change interface will be called,
12133 * This is the right place to enable back bmps_imps()
12134 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012135 if (pHddCtx->hdd_wlan_suspended)
12136 {
12137 hdd_set_pwrparams(pHddCtx);
12138 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012139 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 goto done;
12141 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012143 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12145 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012146 goto done;
12147 default:
12148 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12149 __func__);
12150 return -EOPNOTSUPP;
12151
12152 }
12153
12154 }
12155 else
12156 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012157 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12158 __func__, hdd_device_modetoString(pAdapter->device_mode),
12159 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012160 return -EOPNOTSUPP;
12161 }
12162
12163
12164 if(pRoamProfile)
12165 {
12166 if ( LastBSSType != pRoamProfile->BSSType )
12167 {
12168 /*interface type changed update in wiphy structure*/
12169 wdev->iftype = type;
12170
12171 /*the BSS mode changed, We need to issue disconnect
12172 if connected or in IBSS disconnect state*/
12173 if ( hdd_connGetConnectedBssType(
12174 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12175 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12176 {
12177 /*need to issue a disconnect to CSR.*/
12178 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12179 if( eHAL_STATUS_SUCCESS ==
12180 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12181 pAdapter->sessionId,
12182 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12183 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012184 ret = wait_for_completion_interruptible_timeout(
12185 &pAdapter->disconnect_comp_var,
12186 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12187 if (ret <= 0)
12188 {
12189 hddLog(VOS_TRACE_LEVEL_ERROR,
12190 FL("wait on disconnect_comp_var failed %ld"), ret);
12191 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012192 }
12193 }
12194 }
12195 }
12196
12197done:
12198 /*set bitmask based on updated value*/
12199 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012200
12201 /* Only STA mode support TM now
12202 * all other mode, TM feature should be disabled */
12203 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12204 (~VOS_STA & pHddCtx->concurrency_mode) )
12205 {
12206 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12207 }
12208
Jeff Johnson295189b2012-06-20 16:38:30 -070012209#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012210 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012211 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 {
12213 //we are ok to do AMP
12214 pHddCtx->isAmpAllowed = VOS_TRUE;
12215 }
12216#endif //WLAN_BTAMP_FEATURE
12217 EXIT();
12218 return 0;
12219}
12220
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012221/*
12222 * FUNCTION: wlan_hdd_cfg80211_change_iface
12223 * wrapper function to protect the actual implementation from SSR.
12224 */
12225int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12226 struct net_device *ndev,
12227 enum nl80211_iftype type,
12228 u32 *flags,
12229 struct vif_params *params
12230 )
12231{
12232 int ret;
12233
12234 vos_ssr_protect(__func__);
12235 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12236 vos_ssr_unprotect(__func__);
12237
12238 return ret;
12239}
12240
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012241#ifdef FEATURE_WLAN_TDLS
12242static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012243 struct net_device *dev,
12244#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12245 const u8 *mac,
12246#else
12247 u8 *mac,
12248#endif
12249 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012250{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012251 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012252 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012253 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012254 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012255 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012256 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012257
12258 ENTER();
12259
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012260 if (!dev) {
12261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12262 return -EINVAL;
12263 }
12264
12265 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12266 if (!pAdapter) {
12267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12268 return -EINVAL;
12269 }
12270
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012271 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012272 {
12273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12274 "Invalid arguments");
12275 return -EINVAL;
12276 }
Hoonki Lee27511902013-03-14 18:19:06 -070012277
12278 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12279 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12280 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012282 "%s: TDLS mode is disabled OR not enabled in FW."
12283 MAC_ADDRESS_STR " Request declined.",
12284 __func__, MAC_ADDR_ARRAY(mac));
12285 return -ENOTSUPP;
12286 }
12287
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012288 if (pHddCtx->isLogpInProgress)
12289 {
12290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12291 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012292 wlan_hdd_tdls_set_link_status(pAdapter,
12293 mac,
12294 eTDLS_LINK_IDLE,
12295 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012296 return -EBUSY;
12297 }
12298
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012299 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012300 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012301
12302 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012304 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12305 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012306 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012307 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012308 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012309
12310 /* in add station, we accept existing valid staId if there is */
12311 if ((0 == update) &&
12312 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12313 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012314 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012316 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012317 " link_status %d. staId %d. add station ignored.",
12318 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012319 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012320 return 0;
12321 }
12322 /* in change station, we accept only when staId is valid */
12323 if ((1 == update) &&
12324 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12325 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12326 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012327 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012329 "%s: " MAC_ADDRESS_STR
12330 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012331 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12332 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12333 mutex_unlock(&pHddCtx->tdls_lock);
12334 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012335 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012336 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012337
12338 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012339 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012340 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12342 "%s: " MAC_ADDRESS_STR
12343 " TDLS setup is ongoing. Request declined.",
12344 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012345 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012346 }
12347
12348 /* first to check if we reached to maximum supported TDLS peer.
12349 TODO: for now, return -EPERM looks working fine,
12350 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012351 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12352 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012353 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12355 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012356 " TDLS Max peer already connected. Request declined."
12357 " Num of peers (%d), Max allowed (%d).",
12358 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12359 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012360 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012361 }
12362 else
12363 {
12364 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012365 mutex_lock(&pHddCtx->tdls_lock);
12366 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012367 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012368 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012369 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12371 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12372 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012373 return -EPERM;
12374 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012375 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012376 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012377 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012378 wlan_hdd_tdls_set_link_status(pAdapter,
12379 mac,
12380 eTDLS_LINK_CONNECTING,
12381 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012382
Jeff Johnsond75fe012013-04-06 10:53:06 -070012383 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012384 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012385 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012387 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012388 if(StaParams->htcap_present)
12389 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012391 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012393 "ht_capa->extended_capabilities: %0x",
12394 StaParams->HTCap.extendedHtCapInfo);
12395 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012397 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012399 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012400 if(StaParams->vhtcap_present)
12401 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012403 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12404 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12405 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12406 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012407 {
12408 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012410 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012412 "[%d]: %x ", i, StaParams->supported_rates[i]);
12413 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012414 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012415 else if ((1 == update) && (NULL == StaParams))
12416 {
12417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12418 "%s : update is true, but staParams is NULL. Error!", __func__);
12419 return -EPERM;
12420 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012421
12422 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12423
12424 if (!update)
12425 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012426 /*Before adding sta make sure that device exited from BMPS*/
12427 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12428 {
12429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12430 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12431 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12432 if (status != VOS_STATUS_SUCCESS) {
12433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12434 }
12435 }
12436
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012437 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012438 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012439 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012440 hddLog(VOS_TRACE_LEVEL_ERROR,
12441 FL("Failed to add TDLS peer STA. Enable Bmps"));
12442 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012443 return -EPERM;
12444 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012445 }
12446 else
12447 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012448 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012449 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012450 if (ret != eHAL_STATUS_SUCCESS) {
12451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12452 return -EPERM;
12453 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012454 }
12455
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012456 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012457 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12458
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012459 mutex_lock(&pHddCtx->tdls_lock);
12460 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12461
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012462 if ((pTdlsPeer != NULL) &&
12463 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012464 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012465 hddLog(VOS_TRACE_LEVEL_ERROR,
12466 FL("peer link status %u"), pTdlsPeer->link_status);
12467 mutex_unlock(&pHddCtx->tdls_lock);
12468 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012469 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012470 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012471
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012472 if (ret <= 0)
12473 {
12474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12475 "%s: timeout waiting for tdls add station indication %ld",
12476 __func__, ret);
12477 goto error;
12478 }
12479
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012480 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12481 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012483 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012484 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012485 }
12486
12487 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012488
12489error:
Atul Mittal115287b2014-07-08 13:26:33 +053012490 wlan_hdd_tdls_set_link_status(pAdapter,
12491 mac,
12492 eTDLS_LINK_IDLE,
12493 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012494 return -EPERM;
12495
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012496}
12497#endif
12498
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012499static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012501#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12502 const u8 *mac,
12503#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012504 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012505#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 struct station_parameters *params)
12507{
12508 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012509 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012510 hdd_context_t *pHddCtx;
12511 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012513 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012514#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012515 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012516 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012517 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012518 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012519#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012520
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012521 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012522
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012523 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012524 if ((NULL == pAdapter))
12525 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012527 "invalid adapter ");
12528 return -EINVAL;
12529 }
12530
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012531 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12532 TRACE_CODE_HDD_CHANGE_STATION,
12533 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012534 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012535
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012536 ret = wlan_hdd_validate_context(pHddCtx);
12537 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012538 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012539 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012540 }
12541
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012542 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12543
12544 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012545 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12547 "invalid HDD station context");
12548 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012549 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12551
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012552 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12553 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012554 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012555 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012557 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 WLANTL_STA_AUTHENTICATED);
12559
Gopichand Nakkala29149562013-05-10 21:43:41 +053012560 if (status != VOS_STATUS_SUCCESS)
12561 {
12562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12563 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12564 return -EINVAL;
12565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 }
12567 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012568 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12569 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012570#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012571 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12572 StaParams.capability = params->capability;
12573 StaParams.uapsd_queues = params->uapsd_queues;
12574 StaParams.max_sp = params->max_sp;
12575
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012576 /* Convert (first channel , number of channels) tuple to
12577 * the total list of channels. This goes with the assumption
12578 * that if the first channel is < 14, then the next channels
12579 * are an incremental of 1 else an incremental of 4 till the number
12580 * of channels.
12581 */
12582 if (0 != params->supported_channels_len) {
12583 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12584 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12585 {
12586 int wifi_chan_index;
12587 StaParams.supported_channels[j] = params->supported_channels[i];
12588 wifi_chan_index =
12589 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12590 no_of_channels = params->supported_channels[i+1];
12591 for(k=1; k <= no_of_channels; k++)
12592 {
12593 StaParams.supported_channels[j+1] =
12594 StaParams.supported_channels[j] + wifi_chan_index;
12595 j+=1;
12596 }
12597 }
12598 StaParams.supported_channels_len = j;
12599 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012600 if (params->supported_oper_classes_len >
12601 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12603 "received oper classes:%d, resetting it to max supported %d",
12604 params->supported_oper_classes_len,
12605 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12606 params->supported_oper_classes_len =
12607 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12608 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012609 vos_mem_copy(StaParams.supported_oper_classes,
12610 params->supported_oper_classes,
12611 params->supported_oper_classes_len);
12612 StaParams.supported_oper_classes_len =
12613 params->supported_oper_classes_len;
12614
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012615 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12617 "received extn capabilities:%d, resetting it to max supported",
12618 params->ext_capab_len);
12619 params->ext_capab_len = sizeof(StaParams.extn_capability);
12620 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012621 if (0 != params->ext_capab_len)
12622 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012623 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012624
12625 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012626 {
12627 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012628 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012629 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012630
12631 StaParams.supported_rates_len = params->supported_rates_len;
12632
12633 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12634 * The supported_rates array , for all the structures propogating till Add Sta
12635 * to the firmware has to be modified , if the supplicant (ieee80211) is
12636 * modified to send more rates.
12637 */
12638
12639 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12640 */
12641 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12642 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12643
12644 if (0 != StaParams.supported_rates_len) {
12645 int i = 0;
12646 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12647 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012649 "Supported Rates with Length %d", StaParams.supported_rates_len);
12650 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012652 "[%d]: %0x", i, StaParams.supported_rates[i]);
12653 }
12654
12655 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012656 {
12657 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012658 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012659 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012660
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012661 if (0 != params->ext_capab_len ) {
12662 /*Define A Macro : TODO Sunil*/
12663 if ((1<<4) & StaParams.extn_capability[3]) {
12664 isBufSta = 1;
12665 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012666 /* TDLS Channel Switching Support */
12667 if ((1<<6) & StaParams.extn_capability[3]) {
12668 isOffChannelSupported = 1;
12669 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012670 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012671
12672 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012673 (params->ht_capa || params->vht_capa ||
12674 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012675 /* TDLS Peer is WME/QoS capable */
12676 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012677
12678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12679 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12680 __func__, isQosWmmSta, StaParams.htcap_present);
12681
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012682 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12683 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012684 isOffChannelSupported,
12685 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012686
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012687 if (VOS_STATUS_SUCCESS != status) {
12688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12689 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12690 return -EINVAL;
12691 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012692 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12693
12694 if (VOS_STATUS_SUCCESS != status) {
12695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12696 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12697 return -EINVAL;
12698 }
12699 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012700#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012701 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012702 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 return status;
12704}
12705
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012706#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12707static int wlan_hdd_change_station(struct wiphy *wiphy,
12708 struct net_device *dev,
12709 const u8 *mac,
12710 struct station_parameters *params)
12711#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012712static int wlan_hdd_change_station(struct wiphy *wiphy,
12713 struct net_device *dev,
12714 u8 *mac,
12715 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012716#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012717{
12718 int ret;
12719
12720 vos_ssr_protect(__func__);
12721 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12722 vos_ssr_unprotect(__func__);
12723
12724 return ret;
12725}
12726
Jeff Johnson295189b2012-06-20 16:38:30 -070012727/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012728 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 * This function is used to initialize the key information
12730 */
12731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012732static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012733 struct net_device *ndev,
12734 u8 key_index, bool pairwise,
12735 const u8 *mac_addr,
12736 struct key_params *params
12737 )
12738#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012739static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 struct net_device *ndev,
12741 u8 key_index, const u8 *mac_addr,
12742 struct key_params *params
12743 )
12744#endif
12745{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012747 tCsrRoamSetKey setKey;
12748 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012749 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012750 v_U32_t roamId= 0xFF;
12751 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012752 hdd_hostapd_state_t *pHostapdState;
12753 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012754 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012755 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012756 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012757 v_MACADDR_t *peerMacAddr;
12758 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012759 uint8_t staid = HDD_MAX_STA_COUNT;
12760 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012761
12762 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012763
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12765 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12766 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012767 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012769 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012771 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012772 }
12773
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12775 __func__, hdd_device_modetoString(pAdapter->device_mode),
12776 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012777
12778 if (CSR_MAX_NUM_KEY <= key_index)
12779 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012781 key_index);
12782
12783 return -EINVAL;
12784 }
12785
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012786 if (CSR_MAX_KEY_LEN < params->key_len)
12787 {
12788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12789 params->key_len);
12790
12791 return -EINVAL;
12792 }
12793
Jingxiang Gec438aea2017-10-26 16:44:00 +080012794 if (CSR_MAX_RSC_LEN < params->seq_len)
12795 {
12796 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12797 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012798
12799 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012800 }
12801
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012802 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012803 "%s: called with key index = %d & key length %d & seq length %d",
12804 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012805
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012806 peerMacAddr = (v_MACADDR_t *)mac_addr;
12807
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 /*extract key idx, key len and key*/
12809 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12810 setKey.keyId = key_index;
12811 setKey.keyLength = params->key_len;
12812 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012813 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012814
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012815 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012816 {
12817 case WLAN_CIPHER_SUITE_WEP40:
12818 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12819 break;
12820
12821 case WLAN_CIPHER_SUITE_WEP104:
12822 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12823 break;
12824
12825 case WLAN_CIPHER_SUITE_TKIP:
12826 {
12827 u8 *pKey = &setKey.Key[0];
12828 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12829
12830 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12831
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012832 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012833
12834 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012835 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 |--------------|----------|----------|
12837 <---16bytes---><--8bytes--><--8bytes-->
12838
12839 */
12840 /*Sme expects the 32 bytes key to be in the below order
12841
12842 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012843 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012844 |--------------|----------|----------|
12845 <---16bytes---><--8bytes--><--8bytes-->
12846 */
12847 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012848 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012849
12850 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012851 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012852
12853 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012854 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012855
12856
12857 break;
12858 }
12859
12860 case WLAN_CIPHER_SUITE_CCMP:
12861 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12862 break;
12863
12864#ifdef FEATURE_WLAN_WAPI
12865 case WLAN_CIPHER_SUITE_SMS4:
12866 {
12867 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12868 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12869 params->key, params->key_len);
12870 return 0;
12871 }
12872#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012873
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012874#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 case WLAN_CIPHER_SUITE_KRK:
12876 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12877 break;
12878#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012879
12880#ifdef WLAN_FEATURE_11W
12881 case WLAN_CIPHER_SUITE_AES_CMAC:
12882 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012883 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012884#endif
12885
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012889 status = -EOPNOTSUPP;
12890 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 }
12892
12893 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12894 __func__, setKey.encType);
12895
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012896 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012897#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12898 (!pairwise)
12899#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012900 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012901#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012902 )
12903 {
12904 /* set group key*/
12905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12906 "%s- %d: setting Broadcast key",
12907 __func__, __LINE__);
12908 setKey.keyDirection = eSIR_RX_ONLY;
12909 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12910 }
12911 else
12912 {
12913 /* set pairwise key*/
12914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12915 "%s- %d: setting pairwise key",
12916 __func__, __LINE__);
12917 setKey.keyDirection = eSIR_TX_RX;
12918 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012919 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012920 }
12921 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12922 {
12923 setKey.keyDirection = eSIR_TX_RX;
12924 /*Set the group key*/
12925 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12926 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012927
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012928 if ( 0 != status )
12929 {
12930 hddLog(VOS_TRACE_LEVEL_ERROR,
12931 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012932 status = -EINVAL;
12933 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012934 }
12935 /*Save the keys here and call sme_RoamSetKey for setting
12936 the PTK after peer joins the IBSS network*/
12937 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12938 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012939 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012940 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012941 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12942 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12943 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012945 if( pHostapdState->bssState == BSS_START )
12946 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012947 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12948 vos_status = wlan_hdd_check_ula_done(pAdapter);
12949
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012950 if (peerMacAddr && (pairwise_set_key == true))
12951 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012952
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012953 if ( vos_status != VOS_STATUS_SUCCESS )
12954 {
12955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12956 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12957 __LINE__, vos_status );
12958
12959 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12960
12961 status = -EINVAL;
12962 goto end;
12963 }
12964
Jeff Johnson295189b2012-06-20 16:38:30 -070012965 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12966
12967 if ( status != eHAL_STATUS_SUCCESS )
12968 {
12969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12970 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12971 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012972 status = -EINVAL;
12973 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012974 }
12975 }
12976
12977 /* Saving WEP keys */
12978 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12979 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12980 {
12981 //Save the wep key in ap context. Issue setkey after the BSS is started.
12982 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12983 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12984 }
12985 else
12986 {
12987 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012988 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012989 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12990 }
12991 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012992 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12993 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 {
12995 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12996 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12997
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12999 if (!pairwise)
13000#else
13001 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13002#endif
13003 {
13004 /* set group key*/
13005 if (pHddStaCtx->roam_info.deferKeyComplete)
13006 {
13007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13008 "%s- %d: Perform Set key Complete",
13009 __func__, __LINE__);
13010 hdd_PerformRoamSetKeyComplete(pAdapter);
13011 }
13012 }
13013
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013014 if (pairwise_set_key == true)
13015 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013016
Jeff Johnson295189b2012-06-20 16:38:30 -070013017 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13018
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013019 pWextState->roamProfile.Keys.defaultIndex = key_index;
13020
13021
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013022 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 params->key, params->key_len);
13024
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013025
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13027
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013028 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013030 __func__, setKey.peerMac[0], setKey.peerMac[1],
13031 setKey.peerMac[2], setKey.peerMac[3],
13032 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013033 setKey.keyDirection);
13034
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013035 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013036
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013037 if ( vos_status != VOS_STATUS_SUCCESS )
13038 {
13039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013040 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13041 __LINE__, vos_status );
13042
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013043 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013044
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013045 status = -EINVAL;
13046 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013047
13048 }
13049
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013050#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013051 /* The supplicant may attempt to set the PTK once pre-authentication
13052 is done. Save the key in the UMAC and include it in the ADD BSS
13053 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013054 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013055 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013056 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013057 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13058 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013059 status = 0;
13060 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013061 }
13062 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13063 {
13064 hddLog(VOS_TRACE_LEVEL_ERROR,
13065 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013066 status = -EINVAL;
13067 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013068 }
13069#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013070
13071 /* issue set key request to SME*/
13072 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13073 pAdapter->sessionId, &setKey, &roamId );
13074
13075 if ( 0 != status )
13076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013077 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13079 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013080 status = -EINVAL;
13081 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 }
13083
13084
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013085 /* in case of IBSS as there was no information available about WEP keys during
13086 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013087 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013088 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13089 !( ( IW_AUTH_KEY_MGMT_802_1X
13090 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13092 )
13093 &&
13094 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13095 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13096 )
13097 )
13098 {
13099 setKey.keyDirection = eSIR_RX_ONLY;
13100 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13101
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013102 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 __func__, setKey.peerMac[0], setKey.peerMac[1],
13105 setKey.peerMac[2], setKey.peerMac[3],
13106 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 setKey.keyDirection);
13108
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013109 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 pAdapter->sessionId, &setKey, &roamId );
13111
13112 if ( 0 != status )
13113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013114 hddLog(VOS_TRACE_LEVEL_ERROR,
13115 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013116 __func__, status);
13117 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013118 status = -EINVAL;
13119 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013120 }
13121 }
13122 }
13123
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013124 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013125 for (i = 0; i < params->seq_len; i++) {
13126 rsc_counter |= (params->seq[i] << i*8);
13127 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013128 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13129 }
13130
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013131end:
13132 /* Need to clear any trace of key value in the memory.
13133 * Thus zero out the memory even though it is local
13134 * variable.
13135 */
13136 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013137 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013138 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013139}
13140
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013141#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13142static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13143 struct net_device *ndev,
13144 u8 key_index, bool pairwise,
13145 const u8 *mac_addr,
13146 struct key_params *params
13147 )
13148#else
13149static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13150 struct net_device *ndev,
13151 u8 key_index, const u8 *mac_addr,
13152 struct key_params *params
13153 )
13154#endif
13155{
13156 int ret;
13157 vos_ssr_protect(__func__);
13158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13159 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13160 mac_addr, params);
13161#else
13162 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13163 params);
13164#endif
13165 vos_ssr_unprotect(__func__);
13166
13167 return ret;
13168}
13169
Jeff Johnson295189b2012-06-20 16:38:30 -070013170/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013171 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013172 * This function is used to get the key information
13173 */
13174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013175static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013176 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013178 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013179 const u8 *mac_addr, void *cookie,
13180 void (*callback)(void *cookie, struct key_params*)
13181 )
13182#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013183static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013184 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013185 struct net_device *ndev,
13186 u8 key_index, const u8 *mac_addr, void *cookie,
13187 void (*callback)(void *cookie, struct key_params*)
13188 )
13189#endif
13190{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013191 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013192 hdd_wext_state_t *pWextState = NULL;
13193 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013194 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013195 hdd_context_t *pHddCtx;
13196 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013197
13198 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013199
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013200 if (NULL == pAdapter)
13201 {
13202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13203 "%s: HDD adapter is Null", __func__);
13204 return -ENODEV;
13205 }
13206
13207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13208 ret = wlan_hdd_validate_context(pHddCtx);
13209 if (0 != ret)
13210 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013211 return ret;
13212 }
13213
13214 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13215 pRoamProfile = &(pWextState->roamProfile);
13216
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013217 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13218 __func__, hdd_device_modetoString(pAdapter->device_mode),
13219 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013220
Jeff Johnson295189b2012-06-20 16:38:30 -070013221 memset(&params, 0, sizeof(params));
13222
13223 if (CSR_MAX_NUM_KEY <= key_index)
13224 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013227 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013228
13229 switch(pRoamProfile->EncryptionType.encryptionType[0])
13230 {
13231 case eCSR_ENCRYPT_TYPE_NONE:
13232 params.cipher = IW_AUTH_CIPHER_NONE;
13233 break;
13234
13235 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13236 case eCSR_ENCRYPT_TYPE_WEP40:
13237 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13238 break;
13239
13240 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13241 case eCSR_ENCRYPT_TYPE_WEP104:
13242 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13243 break;
13244
13245 case eCSR_ENCRYPT_TYPE_TKIP:
13246 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13247 break;
13248
13249 case eCSR_ENCRYPT_TYPE_AES:
13250 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13251 break;
13252
13253 default:
13254 params.cipher = IW_AUTH_CIPHER_NONE;
13255 break;
13256 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013257
c_hpothuaaf19692014-05-17 17:01:48 +053013258 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13259 TRACE_CODE_HDD_CFG80211_GET_KEY,
13260 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013261
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13263 params.seq_len = 0;
13264 params.seq = NULL;
13265 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13266 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013267 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013268 return 0;
13269}
13270
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13272static int wlan_hdd_cfg80211_get_key(
13273 struct wiphy *wiphy,
13274 struct net_device *ndev,
13275 u8 key_index, bool pairwise,
13276 const u8 *mac_addr, void *cookie,
13277 void (*callback)(void *cookie, struct key_params*)
13278 )
13279#else
13280static int wlan_hdd_cfg80211_get_key(
13281 struct wiphy *wiphy,
13282 struct net_device *ndev,
13283 u8 key_index, const u8 *mac_addr, void *cookie,
13284 void (*callback)(void *cookie, struct key_params*)
13285 )
13286#endif
13287{
13288 int ret;
13289
13290 vos_ssr_protect(__func__);
13291#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13292 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13293 mac_addr, cookie, callback);
13294#else
13295 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13296 callback);
13297#endif
13298 vos_ssr_unprotect(__func__);
13299
13300 return ret;
13301}
13302
Jeff Johnson295189b2012-06-20 16:38:30 -070013303/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013304 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013305 * This function is used to delete the key information
13306 */
13307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013308static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013309 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013310 u8 key_index,
13311 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013312 const u8 *mac_addr
13313 )
13314#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013315static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 struct net_device *ndev,
13317 u8 key_index,
13318 const u8 *mac_addr
13319 )
13320#endif
13321{
13322 int status = 0;
13323
13324 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013325 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 //it is observed that this is invalidating peer
13327 //key index whenever re-key is done. This is affecting data link.
13328 //It should be ok to ignore del_key.
13329#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13331 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13333 tCsrRoamSetKey setKey;
13334 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013335
Jeff Johnson295189b2012-06-20 16:38:30 -070013336 ENTER();
13337
13338 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13339 __func__,pAdapter->device_mode);
13340
13341 if (CSR_MAX_NUM_KEY <= key_index)
13342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013344 key_index);
13345
13346 return -EINVAL;
13347 }
13348
13349 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13350 setKey.keyId = key_index;
13351
13352 if (mac_addr)
13353 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13354 else
13355 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13356
13357 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13358
13359 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013360 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013361 )
13362 {
13363
13364 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13366 if( pHostapdState->bssState == BSS_START)
13367 {
13368 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013369
Jeff Johnson295189b2012-06-20 16:38:30 -070013370 if ( status != eHAL_STATUS_SUCCESS )
13371 {
13372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13373 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13374 __LINE__, status );
13375 }
13376 }
13377 }
13378 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013379 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 )
13381 {
13382 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13383
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013384 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13385
13386 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013388 __func__, setKey.peerMac[0], setKey.peerMac[1],
13389 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013391 if(pAdapter->sessionCtx.station.conn_info.connState ==
13392 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013394 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013395 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013396
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 if ( 0 != status )
13398 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013399 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013400 "%s: sme_RoamSetKey failure, returned %d",
13401 __func__, status);
13402 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13403 return -EINVAL;
13404 }
13405 }
13406 }
13407#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013408 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 return status;
13410}
13411
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13413static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13414 struct net_device *ndev,
13415 u8 key_index,
13416 bool pairwise,
13417 const u8 *mac_addr
13418 )
13419#else
13420static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13421 struct net_device *ndev,
13422 u8 key_index,
13423 const u8 *mac_addr
13424 )
13425#endif
13426{
13427 int ret;
13428
13429 vos_ssr_protect(__func__);
13430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13431 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13432 mac_addr);
13433#else
13434 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13435#endif
13436 vos_ssr_unprotect(__func__);
13437
13438 return ret;
13439}
13440
Jeff Johnson295189b2012-06-20 16:38:30 -070013441/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013442 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 * This function is used to set the default tx key index
13444 */
13445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013446static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013447 struct net_device *ndev,
13448 u8 key_index,
13449 bool unicast, bool multicast)
13450#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013451static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 struct net_device *ndev,
13453 u8 key_index)
13454#endif
13455{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013457 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013458 hdd_wext_state_t *pWextState;
13459 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013460 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013461
13462 ENTER();
13463
Gopichand Nakkala29149562013-05-10 21:43:41 +053013464 if ((NULL == pAdapter))
13465 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013467 "invalid adapter");
13468 return -EINVAL;
13469 }
13470
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013471 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13472 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13473 pAdapter->sessionId, key_index));
13474
Gopichand Nakkala29149562013-05-10 21:43:41 +053013475 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13476 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13477
13478 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13479 {
13480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13481 "invalid Wext state or HDD context");
13482 return -EINVAL;
13483 }
13484
Arif Hussain6d2a3322013-11-17 19:50:10 -080013485 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013486 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013487
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 if (CSR_MAX_NUM_KEY <= key_index)
13489 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 key_index);
13492
13493 return -EINVAL;
13494 }
13495
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13497 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013498 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013499 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013500 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013502
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013505 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013506 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013507 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013508 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013509#ifdef FEATURE_WLAN_WAPI
13510 (eCSR_ENCRYPT_TYPE_WPI !=
13511 pHddStaCtx->conn_info.ucEncryptionType) &&
13512#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013513 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013514 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013516 {
13517 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013519
Jeff Johnson295189b2012-06-20 16:38:30 -070013520 tCsrRoamSetKey setKey;
13521 v_U32_t roamId= 0xFF;
13522 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013523
13524 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013525 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013526
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 Keys->defaultIndex = (u8)key_index;
13528 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13529 setKey.keyId = key_index;
13530 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013531
13532 vos_mem_copy(&setKey.Key[0],
13533 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013535
Gopichand Nakkala29149562013-05-10 21:43:41 +053013536 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013537
13538 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 &pHddStaCtx->conn_info.bssId[0],
13540 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013541
Gopichand Nakkala29149562013-05-10 21:43:41 +053013542 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13543 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13544 eCSR_ENCRYPT_TYPE_WEP104)
13545 {
13546 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13547 even though ap is configured for WEP-40 encryption. In this canse the key length
13548 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13549 type(104) and switching encryption type to 40*/
13550 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13551 eCSR_ENCRYPT_TYPE_WEP40;
13552 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13553 eCSR_ENCRYPT_TYPE_WEP40;
13554 }
13555
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013556 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013558
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013560 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013562
Jeff Johnson295189b2012-06-20 16:38:30 -070013563 if ( 0 != status )
13564 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013565 hddLog(VOS_TRACE_LEVEL_ERROR,
13566 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013567 status);
13568 return -EINVAL;
13569 }
13570 }
13571 }
13572
13573 /* In SoftAp mode setting key direction for default mode */
13574 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13575 {
13576 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13577 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13578 (eCSR_ENCRYPT_TYPE_AES !=
13579 pWextState->roamProfile.EncryptionType.encryptionType[0])
13580 )
13581 {
13582 /* Saving key direction for default key index to TX default */
13583 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13584 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13585 }
13586 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013587 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 return status;
13589}
13590
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013591#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13592static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13593 struct net_device *ndev,
13594 u8 key_index,
13595 bool unicast, bool multicast)
13596#else
13597static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13598 struct net_device *ndev,
13599 u8 key_index)
13600#endif
13601{
13602 int ret;
13603 vos_ssr_protect(__func__);
13604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13605 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13606 multicast);
13607#else
13608 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13609#endif
13610 vos_ssr_unprotect(__func__);
13611
13612 return ret;
13613}
13614
Jeff Johnson295189b2012-06-20 16:38:30 -070013615/*
13616 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13617 * This function is used to inform the BSS details to nl80211 interface.
13618 */
13619static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13620 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13621{
13622 struct net_device *dev = pAdapter->dev;
13623 struct wireless_dev *wdev = dev->ieee80211_ptr;
13624 struct wiphy *wiphy = wdev->wiphy;
13625 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13626 int chan_no;
13627 int ie_length;
13628 const char *ie;
13629 unsigned int freq;
13630 struct ieee80211_channel *chan;
13631 int rssi = 0;
13632 struct cfg80211_bss *bss = NULL;
13633
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 if( NULL == pBssDesc )
13635 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013636 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 return bss;
13638 }
13639
13640 chan_no = pBssDesc->channelId;
13641 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13642 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13643
13644 if( NULL == ie )
13645 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013646 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 return bss;
13648 }
13649
13650#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13651 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13652 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013653 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 }
13655 else
13656 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013657 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 }
13659#else
13660 freq = ieee80211_channel_to_frequency(chan_no);
13661#endif
13662
13663 chan = __ieee80211_get_channel(wiphy, freq);
13664
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013665 if (!chan) {
13666 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13667 return NULL;
13668 }
13669
Abhishek Singhaee43942014-06-16 18:55:47 +053013670 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013671
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013672 return cfg80211_inform_bss(wiphy, chan,
13673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13674 CFG80211_BSS_FTYPE_UNKNOWN,
13675#endif
13676 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 pBssDesc->capabilityInfo,
13679 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013680 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013681}
13682
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013683/*
13684 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13685 * interface that BSS might have been lost.
13686 * @pAdapter: adaptor
13687 * @bssid: bssid which might have been lost
13688 *
13689 * Return: bss which is unlinked from kernel cache
13690 */
13691struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13692 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13693{
13694 struct net_device *dev = pAdapter->dev;
13695 struct wireless_dev *wdev = dev->ieee80211_ptr;
13696 struct wiphy *wiphy = wdev->wiphy;
13697 struct cfg80211_bss *bss = NULL;
13698
Abhishek Singh5a597e62016-12-05 15:16:30 +053013699 bss = hdd_get_bss_entry(wiphy,
13700 NULL, bssid,
13701 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013702 if (bss == NULL) {
13703 hddLog(LOGE, FL("BSS not present"));
13704 } else {
13705 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13706 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13707 cfg80211_unlink_bss(wiphy, bss);
13708 }
13709 return bss;
13710}
Jeff Johnson295189b2012-06-20 16:38:30 -070013711
13712
13713/*
13714 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13715 * This function is used to inform the BSS details to nl80211 interface.
13716 */
13717struct cfg80211_bss*
13718wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13719 tSirBssDescription *bss_desc
13720 )
13721{
13722 /*
13723 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13724 already exists in bss data base of cfg80211 for that particular BSS ID.
13725 Using cfg80211_inform_bss_frame to update the bss entry instead of
13726 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13727 now there is no possibility to get the mgmt(probe response) frame from PE,
13728 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13729 cfg80211_inform_bss_frame.
13730 */
13731 struct net_device *dev = pAdapter->dev;
13732 struct wireless_dev *wdev = dev->ieee80211_ptr;
13733 struct wiphy *wiphy = wdev->wiphy;
13734 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013735#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13736 qcom_ie_age *qie_age = NULL;
13737 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13738#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013740#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013741 const char *ie =
13742 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13743 unsigned int freq;
13744 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013745 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013746 struct cfg80211_bss *bss_status = NULL;
13747 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13748 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013749 hdd_context_t *pHddCtx;
13750 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013751#ifdef WLAN_OPEN_SOURCE
13752 struct timespec ts;
13753#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013754
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013755
Wilson Yangf80a0542013-10-07 13:02:37 -070013756 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13757 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013758 if (0 != status)
13759 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013760 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013761 }
13762
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013763 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013764 if (!mgmt)
13765 {
13766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13767 "%s: memory allocation failed ", __func__);
13768 return NULL;
13769 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013770
Jeff Johnson295189b2012-06-20 16:38:30 -070013771 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013772
13773#ifdef WLAN_OPEN_SOURCE
13774 /* Android does not want the timestamp from the frame.
13775 Instead it wants a monotonic increasing value */
13776 get_monotonic_boottime(&ts);
13777 mgmt->u.probe_resp.timestamp =
13778 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13779#else
13780 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13782 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013783
13784#endif
13785
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13787 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013788
13789#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13790 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13791 /* Assuming this is the last IE, copy at the end */
13792 ie_length -=sizeof(qcom_ie_age);
13793 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13794 qie_age->element_id = QCOM_VENDOR_IE_ID;
13795 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13796 qie_age->oui_1 = QCOM_OUI1;
13797 qie_age->oui_2 = QCOM_OUI2;
13798 qie_age->oui_3 = QCOM_OUI3;
13799 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013800 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13801 * bss related timestamp is in units of ms. Due to this when scan results
13802 * are sent to lowi the scan age is high.To address this, send age in units
13803 * of 1/10 ms.
13804 */
13805 qie_age->age = (vos_timer_get_system_time() -
13806 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013807#endif
13808
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013810 if (bss_desc->fProbeRsp)
13811 {
13812 mgmt->frame_control |=
13813 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13814 }
13815 else
13816 {
13817 mgmt->frame_control |=
13818 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13819 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013820
13821#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013822 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013823 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013825 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013826 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013827 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013828 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070013829
13830 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013831 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013832 }
13833 else
13834 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13836 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 kfree(mgmt);
13838 return NULL;
13839 }
13840#else
13841 freq = ieee80211_channel_to_frequency(chan_no);
13842#endif
13843 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013844 /*when the band is changed on the fly using the GUI, three things are done
13845 * 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)
13846 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13847 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13848 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13849 * and discards the channels correponding to previous band and calls back with zero bss results.
13850 * 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
13851 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13852 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13853 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13854 * So drop the bss and continue to next bss.
13855 */
13856 if(chan == NULL)
13857 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013858 hddLog(VOS_TRACE_LEVEL_ERROR,
13859 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13860 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013861 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013862 return NULL;
13863 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013864 /*To keep the rssi icon of the connected AP in the scan window
13865 *and the rssi icon of the wireless networks in sync
13866 * */
13867 if (( eConnectionState_Associated ==
13868 pAdapter->sessionCtx.station.conn_info.connState ) &&
13869 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13870 pAdapter->sessionCtx.station.conn_info.bssId,
13871 WNI_CFG_BSSID_LEN)) &&
13872 (pHddCtx->hdd_wlan_suspended == FALSE))
13873 {
13874 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13875 rssi = (pAdapter->rssi * 100);
13876 }
13877 else
13878 {
13879 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13880 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013881
Nirav Shah20ac06f2013-12-12 18:14:06 +053013882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013883 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13884 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013885
Jeff Johnson295189b2012-06-20 16:38:30 -070013886 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13887 frame_len, rssi, GFP_KERNEL);
13888 kfree(mgmt);
13889 return bss_status;
13890}
13891
13892/*
13893 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13894 * This function is used to update the BSS data base of CFG8011
13895 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 tCsrRoamInfo *pRoamInfo
13898 )
13899{
13900 tCsrRoamConnectedProfile roamProfile;
13901 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13902 struct cfg80211_bss *bss = NULL;
13903
13904 ENTER();
13905
13906 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13907 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13908
13909 if (NULL != roamProfile.pBssDesc)
13910 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013911 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13912 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013913
13914 if (NULL == bss)
13915 {
13916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13917 __func__);
13918 }
13919
13920 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13921 }
13922 else
13923 {
13924 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13925 __func__);
13926 }
13927 return bss;
13928}
13929
13930/*
13931 * FUNCTION: wlan_hdd_cfg80211_update_bss
13932 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013933static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13934 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013936{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013937 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 tCsrScanResultInfo *pScanResult;
13939 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013940 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 tScanResultHandle pResult;
13942 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013943 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013944 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013946
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013947 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13948 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13949 NO_SESSION, pAdapter->sessionId));
13950
Wilson Yangf80a0542013-10-07 13:02:37 -070013951 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013952 ret = wlan_hdd_validate_context(pHddCtx);
13953 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013955 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013956 }
13957
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013958 if (pAdapter->request != NULL)
13959 {
13960 if ((pAdapter->request->n_ssids == 1)
13961 && (pAdapter->request->ssids != NULL)
13962 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13963 is_p2p_scan = true;
13964 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 /*
13966 * start getting scan results and populate cgf80211 BSS database
13967 */
13968 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13969
13970 /* no scan results */
13971 if (NULL == pResult)
13972 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13974 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013975 wlan_hdd_get_frame_logs(pAdapter,
13976 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013977 return status;
13978 }
13979
13980 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13981
13982 while (pScanResult)
13983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 /*
13985 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13986 * entry already exists in bss data base of cfg80211 for that
13987 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13988 * bss entry instead of cfg80211_inform_bss, But this call expects
13989 * mgmt packet as input. As of now there is no possibility to get
13990 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 * ieee80211_mgmt(probe response) and passing to c
13992 * fg80211_inform_bss_frame.
13993 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013994 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13995 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13996 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013997 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13998 continue; //Skip the non p2p bss entries
13999 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14001 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014002
Jeff Johnson295189b2012-06-20 16:38:30 -070014003
14004 if (NULL == bss_status)
14005 {
14006 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014007 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014008 }
14009 else
14010 {
Yue Maf49ba872013-08-19 12:04:25 -070014011 cfg80211_put_bss(
14012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14013 wiphy,
14014#endif
14015 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 }
14017
14018 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14019 }
14020
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014021 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014022 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014023 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014024}
14025
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014026void
14027hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14028{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014029 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014030 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014031} /****** end hddPrintMacAddr() ******/
14032
14033void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014034hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014035{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014037 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014038 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14039 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14040 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014041} /****** end hddPrintPmkId() ******/
14042
14043//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14044//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14045
14046//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14047//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14048
14049#define dump_bssid(bssid) \
14050 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014051 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14052 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014053 }
14054
14055#define dump_pmkid(pMac, pmkid) \
14056 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014057 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14058 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014059 }
14060
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014061#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014062/*
14063 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14064 * This function is used to notify the supplicant of a new PMKSA candidate.
14065 */
14066int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014067 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014068 int index, bool preauth )
14069{
Jeff Johnsone7245742012-09-05 17:12:55 -070014070#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014071 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014072 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014073
14074 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014075 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014076
14077 if( NULL == pRoamInfo )
14078 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014079 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014080 return -EINVAL;
14081 }
14082
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014083 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14084 {
14085 dump_bssid(pRoamInfo->bssid);
14086 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014087 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014088 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014089#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014090 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014091}
14092#endif //FEATURE_WLAN_LFR
14093
Yue Maef608272013-04-08 23:09:17 -070014094#ifdef FEATURE_WLAN_LFR_METRICS
14095/*
14096 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14097 * 802.11r/LFR metrics reporting function to report preauth initiation
14098 *
14099 */
14100#define MAX_LFR_METRICS_EVENT_LENGTH 100
14101VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14102 tCsrRoamInfo *pRoamInfo)
14103{
14104 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14105 union iwreq_data wrqu;
14106
14107 ENTER();
14108
14109 if (NULL == pAdapter)
14110 {
14111 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14112 return VOS_STATUS_E_FAILURE;
14113 }
14114
14115 /* create the event */
14116 memset(&wrqu, 0, sizeof(wrqu));
14117 memset(metrics_notification, 0, sizeof(metrics_notification));
14118
14119 wrqu.data.pointer = metrics_notification;
14120 wrqu.data.length = scnprintf(metrics_notification,
14121 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14122 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14123
14124 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14125
14126 EXIT();
14127
14128 return VOS_STATUS_SUCCESS;
14129}
14130
14131/*
14132 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14133 * 802.11r/LFR metrics reporting function to report preauth completion
14134 * or failure
14135 */
14136VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14137 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14138{
14139 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14140 union iwreq_data wrqu;
14141
14142 ENTER();
14143
14144 if (NULL == pAdapter)
14145 {
14146 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14147 return VOS_STATUS_E_FAILURE;
14148 }
14149
14150 /* create the event */
14151 memset(&wrqu, 0, sizeof(wrqu));
14152 memset(metrics_notification, 0, sizeof(metrics_notification));
14153
14154 scnprintf(metrics_notification, sizeof(metrics_notification),
14155 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14156 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14157
14158 if (1 == preauth_status)
14159 strncat(metrics_notification, " TRUE", 5);
14160 else
14161 strncat(metrics_notification, " FALSE", 6);
14162
14163 wrqu.data.pointer = metrics_notification;
14164 wrqu.data.length = strlen(metrics_notification);
14165
14166 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14167
14168 EXIT();
14169
14170 return VOS_STATUS_SUCCESS;
14171}
14172
14173/*
14174 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14175 * 802.11r/LFR metrics reporting function to report handover initiation
14176 *
14177 */
14178VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14179 tCsrRoamInfo *pRoamInfo)
14180{
14181 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14182 union iwreq_data wrqu;
14183
14184 ENTER();
14185
14186 if (NULL == pAdapter)
14187 {
14188 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14189 return VOS_STATUS_E_FAILURE;
14190 }
14191
14192 /* create the event */
14193 memset(&wrqu, 0, sizeof(wrqu));
14194 memset(metrics_notification, 0, sizeof(metrics_notification));
14195
14196 wrqu.data.pointer = metrics_notification;
14197 wrqu.data.length = scnprintf(metrics_notification,
14198 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14199 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14200
14201 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14202
14203 EXIT();
14204
14205 return VOS_STATUS_SUCCESS;
14206}
14207#endif
14208
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014209
14210/**
14211 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14212 * @scan_req: scan request to be checked
14213 *
14214 * Return: true or false
14215 */
14216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14217static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14218 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014219 *scan_req, hdd_context_t
14220 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014221{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014222 if (!scan_req || !scan_req->wiphy ||
14223 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014224 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14225 return false;
14226 }
14227 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14228 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14229 return false;
14230 }
14231 return true;
14232}
14233#else
14234static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14235 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014236 *scan_req, hdd_context_t
14237 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014238{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014239 if (!scan_req || !scan_req->wiphy ||
14240 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014241 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14242 return false;
14243 }
14244 return true;
14245}
14246#endif
14247
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14249/**
14250 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14251 * @adapter: Pointer to the adapter
14252 * @req : Scan request
14253 * @aborted : true scan aborted false scan success
14254 *
14255 * This function notifies scan done to cfg80211
14256 *
14257 * Return: none
14258 */
14259static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14260 struct cfg80211_scan_request *req,
14261 bool aborted)
14262{
14263 struct cfg80211_scan_info info = {
14264 .aborted = aborted
14265 };
14266
14267 if (adapter->dev->flags & IFF_UP)
14268 cfg80211_scan_done(req, &info);
14269 else
14270 hddLog(LOGW,
14271 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14272}
14273#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14274/**
14275 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14276 * @adapter: Pointer to the adapter
14277 * @req : Scan request
14278 * @aborted : true scan aborted false scan success
14279 *
14280 * This function notifies scan done to cfg80211
14281 *
14282 * Return: none
14283 */
14284static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14285 struct cfg80211_scan_request *req,
14286 bool aborted)
14287{
14288 if (adapter->dev->flags & IFF_UP)
14289 cfg80211_scan_done(req, aborted);
14290 else
14291 hddLog(LOGW,
14292 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14293}
14294#else
14295/**
14296 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14297 * @adapter: Pointer to the adapter
14298 * @req : Scan request
14299 * @aborted : true scan aborted false scan success
14300 *
14301 * This function notifies scan done to cfg80211
14302 *
14303 * Return: none
14304 */
14305static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14306 struct cfg80211_scan_request *req,
14307 bool aborted)
14308{
14309 cfg80211_scan_done(req, aborted);
14310}
14311#endif
14312
Mukul Sharmab392b642017-08-17 17:45:29 +053014313#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014314/*
14315 * FUNCTION: hdd_cfg80211_scan_done_callback
14316 * scanning callback function, called after finishing scan
14317 *
14318 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014319static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014320 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14321{
14322 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014323 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014325 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014326 struct cfg80211_scan_request *req = NULL;
14327 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014328 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014329 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014330 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014331
14332 ENTER();
14333
c_manjee1b4ab9a2016-10-26 11:36:55 +053014334 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14335 !pAdapter->dev) {
14336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14337 return 0;
14338 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014339 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014340 if (NULL == pHddCtx) {
14341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014342 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014343 }
14344
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014346 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014347 {
14348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014349 }
14350#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014351 pScanInfo = &pHddCtx->scan_info;
14352
Jeff Johnson295189b2012-06-20 16:38:30 -070014353 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014354 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014355 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014356 __func__, halHandle, pContext, (int) scanId, (int) status);
14357
Kiet Lamac06e2c2013-10-23 16:25:07 +053014358 pScanInfo->mScanPendingCounter = 0;
14359
Jeff Johnson295189b2012-06-20 16:38:30 -070014360 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014361 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014362 &pScanInfo->scan_req_completion_event,
14363 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014364 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014365 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014366 hddLog(VOS_TRACE_LEVEL_ERROR,
14367 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014368 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014369 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014370 }
14371
Yue Maef608272013-04-08 23:09:17 -070014372 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014373 {
14374 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014375 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 }
14377
14378 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014379 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014380 {
14381 hddLog(VOS_TRACE_LEVEL_INFO,
14382 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014383 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014384 (int) scanId);
14385 }
14386
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014387#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014388 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014389#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014390 {
14391 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14392 pAdapter);
14393 if (0 > ret)
14394 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014395 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014396
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 /* If any client wait scan result through WEXT
14398 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014399 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 {
14401 /* The other scan request waiting for current scan finish
14402 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014403 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014404 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014405 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014406 }
14407 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014408 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 {
14410 struct net_device *dev = pAdapter->dev;
14411 union iwreq_data wrqu;
14412 int we_event;
14413 char *msg;
14414
14415 memset(&wrqu, '\0', sizeof(wrqu));
14416 we_event = SIOCGIWSCAN;
14417 msg = NULL;
14418 wireless_send_event(dev, we_event, &wrqu, msg);
14419 }
14420 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014421 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014422
14423 /* Get the Scan Req */
14424 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014425 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014426
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014427 /* Scan is no longer pending */
14428 pScanInfo->mScanPending = VOS_FALSE;
14429
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014430 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014431 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014432#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014434 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014435#endif
14436
14437 if (pAdapter->dev) {
14438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14439 pAdapter->dev->name);
14440 }
mukul sharmae7041822015-12-03 15:09:21 +053014441 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014442 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014443 }
14444
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014445 /* last_scan_timestamp is used to decide if new scan
14446 * is needed or not on station interface. If last station
14447 * scan time and new station scan time is less then
14448 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014449 * Also only last_scan_timestamp is updated here last_scan_channellist
14450 * is updated on receiving scan request itself to make sure kernel
14451 * allocated scan request(scan_req) object is not dereferenced here,
14452 * because interface down, where kernel frees scan_req, may happen any
14453 * time while driver is processing scan_done_callback. So it's better
14454 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014455 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014456 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14457 if (status == eCSR_SCAN_SUCCESS)
14458 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14459 else {
14460 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14461 sizeof(pHddCtx->scan_info.last_scan_channelList));
14462 pHddCtx->scan_info.last_scan_numChannels = 0;
14463 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014464 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014465 }
14466
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014467 /*
14468 * cfg80211_scan_done informing NL80211 about completion
14469 * of scanning
14470 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014471 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14472 {
14473 aborted = true;
14474 }
mukul sharmae7041822015-12-03 15:09:21 +053014475
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014477 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14478 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014479#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014480 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014481
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014482 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014483
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014484allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014485 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14486 ) && (pHddCtx->spoofMacAddr.isEnabled
14487 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014488 /* Generate new random mac addr for next scan */
14489 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014490
14491 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14492 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014493 }
14494
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014495 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014496 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014497
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014498 /* Acquire wakelock to handle the case where APP's tries to suspend
14499 * immediatly after the driver gets connect request(i.e after scan)
14500 * from supplicant, this result in app's is suspending and not able
14501 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014502 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014503
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014505 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014506#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014507#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014508 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014509#endif
14510
Jeff Johnson295189b2012-06-20 16:38:30 -070014511 EXIT();
14512 return 0;
14513}
14514
14515/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014516 * FUNCTION: hdd_isConnectionInProgress
14517 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014518 *
14519 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014520v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14521 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014522{
14523 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14524 hdd_station_ctx_t *pHddStaCtx = NULL;
14525 hdd_adapter_t *pAdapter = NULL;
14526 VOS_STATUS status = 0;
14527 v_U8_t staId = 0;
14528 v_U8_t *staMac = NULL;
14529
14530 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14531
14532 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14533 {
14534 pAdapter = pAdapterNode->pAdapter;
14535
14536 if( pAdapter )
14537 {
14538 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014539 "%s: Adapter with device mode %s (%d) exists",
14540 __func__, hdd_device_modetoString(pAdapter->device_mode),
14541 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014542 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014543 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14544 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14545 (eConnectionState_Connecting ==
14546 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14547 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014548 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014549 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014550 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014551 if (session_id && reason)
14552 {
14553 *session_id = pAdapter->sessionId;
14554 *reason = eHDD_CONNECTION_IN_PROGRESS;
14555 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014556 return VOS_TRUE;
14557 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014558 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014559 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014560 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014561 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014562 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014563 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014564 if (session_id && reason)
14565 {
14566 *session_id = pAdapter->sessionId;
14567 *reason = eHDD_REASSOC_IN_PROGRESS;
14568 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014569 return VOS_TRUE;
14570 }
14571 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014572 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14573 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014574 {
14575 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14576 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014577 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014578 {
14579 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014580 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014581 "%s: client " MAC_ADDRESS_STR
14582 " is in the middle of WPS/EAPOL exchange.", __func__,
14583 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014584 if (session_id && reason)
14585 {
14586 *session_id = pAdapter->sessionId;
14587 *reason = eHDD_EAPOL_IN_PROGRESS;
14588 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014589 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014590 }
14591 }
14592 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14593 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14594 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014595 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14596 ptSapContext pSapCtx = NULL;
14597 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14598 if(pSapCtx == NULL){
14599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14600 FL("psapCtx is NULL"));
14601 return VOS_FALSE;
14602 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014603 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14604 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014605 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14606 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014607 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014608 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014609
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014610 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014611 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14612 "middle of WPS/EAPOL exchange.", __func__,
14613 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014614 if (session_id && reason)
14615 {
14616 *session_id = pAdapter->sessionId;
14617 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14618 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014619 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014620 }
14621 }
14622 }
14623 }
14624 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14625 pAdapterNode = pNext;
14626 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014627 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014628}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014629
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014630/**
14631 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14632 * to the Scan request
14633 * @scanRequest: Pointer to the csr scan request
14634 * @request: Pointer to the scan request from supplicant
14635 *
14636 * Return: None
14637 */
14638#ifdef CFG80211_SCAN_BSSID
14639static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14640 struct cfg80211_scan_request *request)
14641{
14642 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14643}
14644#else
14645static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14646 struct cfg80211_scan_request *request)
14647{
14648}
14649#endif
14650
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014651/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014652 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014653 * this scan respond to scan trigger and update cfg80211 scan database
14654 * later, scan dump command can be used to recieve scan results
14655 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014656int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014657#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14658 struct net_device *dev,
14659#endif
14660 struct cfg80211_scan_request *request)
14661{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014662 hdd_adapter_t *pAdapter = NULL;
14663 hdd_context_t *pHddCtx = NULL;
14664 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014665 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014666 tCsrScanRequest scanRequest;
14667 tANI_U8 *channelList = NULL, i;
14668 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014669 int status;
14670 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014671 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014672 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014673 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014674 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014675 v_U8_t curr_session_id;
14676 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014677
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14679 struct net_device *dev = NULL;
14680 if (NULL == request)
14681 {
14682 hddLog(VOS_TRACE_LEVEL_ERROR,
14683 "%s: scan req param null", __func__);
14684 return -EINVAL;
14685 }
14686 dev = request->wdev->netdev;
14687#endif
14688
14689 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14690 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14691 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14692
Jeff Johnson295189b2012-06-20 16:38:30 -070014693 ENTER();
14694
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014695 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14696 __func__, hdd_device_modetoString(pAdapter->device_mode),
14697 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014698
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014699 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014700 if (0 != status)
14701 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014702 return status;
14703 }
14704
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014705 if (NULL == pwextBuf)
14706 {
14707 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14708 __func__);
14709 return -EIO;
14710 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014711 cfg_param = pHddCtx->cfg_ini;
14712 pScanInfo = &pHddCtx->scan_info;
14713
Jeff Johnson295189b2012-06-20 16:38:30 -070014714#ifdef WLAN_BTAMP_FEATURE
14715 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014716 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014718 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 "%s: No scanning when AMP is on", __func__);
14720 return -EOPNOTSUPP;
14721 }
14722#endif
14723 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014724 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014725 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014726 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014727 "%s: Not scanning on device_mode = %s (%d)",
14728 __func__, hdd_device_modetoString(pAdapter->device_mode),
14729 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014730 return -EOPNOTSUPP;
14731 }
14732
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014733 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14734 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14735 return -EOPNOTSUPP;
14736 }
14737
Jeff Johnson295189b2012-06-20 16:38:30 -070014738 if (TRUE == pScanInfo->mScanPending)
14739 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014740 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14741 {
14742 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14743 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014744 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014745 }
14746
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014747 // Don't allow scan if PNO scan is going on.
14748 if (pHddCtx->isPnoEnable)
14749 {
14750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14751 FL("pno scan in progress"));
14752 return -EBUSY;
14753 }
14754
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014755 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014756 //Channel and action frame is pending
14757 //Otherwise Cancel Remain On Channel and allow Scan
14758 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014759 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014760 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014762 return -EBUSY;
14763 }
14764
Jeff Johnson295189b2012-06-20 16:38:30 -070014765 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14766 {
14767 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014768 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014769 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014770 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014771 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14772 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014773 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 "%s: MAX TM Level Scan not allowed", __func__);
14775 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014776 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014777 }
14778 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14779
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014780 /* Check if scan is allowed at this point of time.
14781 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014782 if (TRUE == pHddCtx->btCoexModeSet)
14783 {
14784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14785 FL("BTCoex Mode operation in progress"));
14786 return -EBUSY;
14787 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014788 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014789 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014790
14791 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14792 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14793 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014794 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14795 pHddCtx->last_scan_reject_reason != curr_reason ||
14796 !pHddCtx->last_scan_reject_timestamp)
14797 {
14798 pHddCtx->last_scan_reject_session_id = curr_session_id;
14799 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014800 pHddCtx->last_scan_reject_timestamp =
14801 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014802 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014803 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014804 else
14805 {
14806 pHddCtx->scan_reject_cnt++;
14807
Abhishek Singhe4b12562017-06-20 16:53:39 +053014808 if ((pHddCtx->scan_reject_cnt >=
14809 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014810 vos_system_time_after(jiffies_to_msecs(jiffies),
14811 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014812 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014813 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14814 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14815 vos_system_time_after(jiffies_to_msecs(jiffies),
14816 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014817 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014818 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014819 if (pHddCtx->cfg_ini->enableFatalEvent)
14820 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14821 WLAN_LOG_INDICATOR_HOST_DRIVER,
14822 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14823 FALSE, FALSE);
14824 else
14825 {
14826 hddLog(LOGE, FL("Triggering SSR"));
14827 vos_wlanRestart();
14828 }
14829 }
14830 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014831 return -EBUSY;
14832 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014833 pHddCtx->last_scan_reject_timestamp = 0;
14834 pHddCtx->last_scan_reject_session_id = 0xFF;
14835 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014836 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014837
Jeff Johnson295189b2012-06-20 16:38:30 -070014838 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14839
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014840 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14841 * Becasue of this, driver is assuming that this is not wildcard scan and so
14842 * is not aging out the scan results.
14843 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014844 if ((request->ssids) && (request->n_ssids == 1) &&
14845 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014846 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014848
14849 if ((request->ssids) && (0 < request->n_ssids))
14850 {
14851 tCsrSSIDInfo *SsidInfo;
14852 int j;
14853 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14854 /* Allocate num_ssid tCsrSSIDInfo structure */
14855 SsidInfo = scanRequest.SSIDs.SSIDList =
14856 ( tCsrSSIDInfo *)vos_mem_malloc(
14857 request->n_ssids*sizeof(tCsrSSIDInfo));
14858
14859 if(NULL == scanRequest.SSIDs.SSIDList)
14860 {
14861 hddLog(VOS_TRACE_LEVEL_ERROR,
14862 "%s: memory alloc failed SSIDInfo buffer", __func__);
14863 return -ENOMEM;
14864 }
14865
14866 /* copy all the ssid's and their length */
14867 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14868 {
14869 /* get the ssid length */
14870 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14871 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14872 SsidInfo->SSID.length);
14873 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14874 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14875 j, SsidInfo->SSID.ssId);
14876 }
14877 /* set the scan type to active */
14878 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14879 }
14880 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014882 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14883 TRACE_CODE_HDD_CFG80211_SCAN,
14884 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014885 /* set the scan type to active */
14886 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014888 else
14889 {
14890 /*Set the scan type to default type, in this case it is ACTIVE*/
14891 scanRequest.scanType = pScanInfo->scan_mode;
14892 }
14893 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14894 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014895
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014896 csr_scan_request_assign_bssid(&scanRequest, request);
14897
Jeff Johnson295189b2012-06-20 16:38:30 -070014898 /* set BSSType to default type */
14899 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14900
14901 /*TODO: scan the requested channels only*/
14902
14903 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014904 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014905 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014906 hddLog(VOS_TRACE_LEVEL_WARN,
14907 "No of Scan Channels exceeded limit: %d", request->n_channels);
14908 request->n_channels = MAX_CHANNEL;
14909 }
14910
14911 hddLog(VOS_TRACE_LEVEL_INFO,
14912 "No of Scan Channels: %d", request->n_channels);
14913
14914
14915 if( request->n_channels )
14916 {
14917 char chList [(request->n_channels*5)+1];
14918 int len;
14919 channelList = vos_mem_malloc( request->n_channels );
14920 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014921 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014922 hddLog(VOS_TRACE_LEVEL_ERROR,
14923 "%s: memory alloc failed channelList", __func__);
14924 status = -ENOMEM;
14925 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014926 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014927
14928 for( i = 0, len = 0; i < request->n_channels ; i++ )
14929 {
14930 channelList[i] = request->channels[i]->hw_value;
14931 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14932 }
14933
Nirav Shah20ac06f2013-12-12 18:14:06 +053014934 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014935 "Channel-List: %s ", chList);
14936 }
c_hpothu53512302014-04-15 18:49:53 +053014937
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014938 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14939 scanRequest.ChannelInfo.ChannelList = channelList;
14940
14941 /* set requestType to full scan */
14942 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14943
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014944 /* if there is back to back scan happening in driver with in
14945 * nDeferScanTimeInterval interval driver should defer new scan request
14946 * and should provide last cached scan results instead of new channel list.
14947 * This rule is not applicable if scan is p2p scan.
14948 * This condition will work only in case when last request no of channels
14949 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014950 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014951 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014952 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014953
Sushant Kaushik86592172015-04-27 16:35:03 +053014954 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14955 /* if wps ie is NULL , then only defer scan */
14956 if ( pWpsIe == NULL &&
14957 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014958 {
14959 if ( pScanInfo->last_scan_timestamp !=0 &&
14960 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14961 {
14962 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14963 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14964 vos_mem_compare(pScanInfo->last_scan_channelList,
14965 channelList, pScanInfo->last_scan_numChannels))
14966 {
14967 hddLog(VOS_TRACE_LEVEL_WARN,
14968 " New and old station scan time differ is less then %u",
14969 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14970
14971 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014972 pAdapter);
14973
Agarwal Ashish57e84372014-12-05 18:26:53 +053014974 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014975 "Return old cached scan as all channels and no of channels are same");
14976
Agarwal Ashish57e84372014-12-05 18:26:53 +053014977 if (0 > ret)
14978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014979
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014980 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014981
14982 status = eHAL_STATUS_SUCCESS;
14983 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014984 }
14985 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014986 }
14987
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014988 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14989 * search (Flush on both full scan and social scan but not on single
14990 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14991 */
14992
14993 /* Supplicant does single channel scan after 8-way handshake
14994 * and in that case driver shoudnt flush scan results. If
14995 * driver flushes the scan results here and unfortunately if
14996 * the AP doesnt respond to our probe req then association
14997 * fails which is not desired
14998 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014999 if ((request->n_ssids == 1)
15000 && (request->ssids != NULL)
15001 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15002 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015003
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015004 if( is_p2p_scan ||
15005 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015006 {
15007 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15008 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15009 pAdapter->sessionId );
15010 }
15011
15012 if( request->ie_len )
15013 {
15014 /* save this for future association (join requires this) */
15015 /*TODO: Array needs to be converted to dynamic allocation,
15016 * as multiple ie.s can be sent in cfg80211_scan_request structure
15017 * CR 597966
15018 */
15019 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15020 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15021 pScanInfo->scanAddIE.length = request->ie_len;
15022
15023 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15024 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15025 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015026 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015027 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015028 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015029 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15030 memcpy( pwextBuf->roamProfile.addIEScan,
15031 request->ie, request->ie_len);
15032 }
15033 else
15034 {
15035 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15036 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015037 }
15038
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015039 }
15040 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15041 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15042
15043 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15044 request->ie_len);
15045 if (pP2pIe != NULL)
15046 {
15047#ifdef WLAN_FEATURE_P2P_DEBUG
15048 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15049 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15050 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015051 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015052 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15053 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15054 "Go nego completed to Connection is started");
15055 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15056 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015057 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015058 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15059 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015060 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015061 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15062 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15063 "Disconnected state to Connection is started");
15064 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15065 "for 4way Handshake");
15066 }
15067#endif
15068
15069 /* no_cck will be set during p2p find to disable 11b rates */
15070 if(TRUE == request->no_cck)
15071 {
15072 hddLog(VOS_TRACE_LEVEL_INFO,
15073 "%s: This is a P2P Search", __func__);
15074 scanRequest.p2pSearch = 1;
15075
15076 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015077 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015078 /* set requestType to P2P Discovery */
15079 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15080 }
15081
15082 /*
15083 Skip Dfs Channel in case of P2P Search
15084 if it is set in ini file
15085 */
15086 if(cfg_param->skipDfsChnlInP2pSearch)
15087 {
15088 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015089 }
15090 else
15091 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015092 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015093 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015094
Agarwal Ashish4f616132013-12-30 23:32:50 +053015095 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015096 }
15097 }
15098
15099 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15100
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015101#ifdef FEATURE_WLAN_TDLS
15102 /* if tdls disagree scan right now, return immediately.
15103 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15104 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15105 */
15106 status = wlan_hdd_tdls_scan_callback (pAdapter,
15107 wiphy,
15108#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15109 dev,
15110#endif
15111 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015112 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015113 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015114 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15116 "scan rejected %d", __func__, status);
15117 else
15118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15119 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015120 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015121 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015122 }
15123#endif
15124
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015125 /* acquire the wakelock to avoid the apps suspend during the scan. To
15126 * address the following issues.
15127 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15128 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15129 * for long time, this result in apps running at full power for long time.
15130 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15131 * be stuck in full power because of resume BMPS
15132 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015133 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015134
Nirav Shah20ac06f2013-12-12 18:14:06 +053015135 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15136 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015137 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15138 scanRequest.requestType, scanRequest.scanType,
15139 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015140 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15141
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015142 if (pHddCtx->spoofMacAddr.isEnabled &&
15143 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015144 {
15145 hddLog(VOS_TRACE_LEVEL_INFO,
15146 "%s: MAC Spoofing enabled for current scan", __func__);
15147 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15148 * to fill TxBds for probe request during current scan
15149 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015150 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015151 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015152
15153 if(status != VOS_STATUS_SUCCESS)
15154 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015155 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015156 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015157#ifdef FEATURE_WLAN_TDLS
15158 wlan_hdd_tdls_scan_done_callback(pAdapter);
15159#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015160 goto free_mem;
15161 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015162 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015163 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015164 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015165 pAdapter->sessionId, &scanRequest, &scanId,
15166 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015167
Jeff Johnson295189b2012-06-20 16:38:30 -070015168 if (eHAL_STATUS_SUCCESS != status)
15169 {
15170 hddLog(VOS_TRACE_LEVEL_ERROR,
15171 "%s: sme_ScanRequest returned error %d", __func__, status);
15172 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015173 if(eHAL_STATUS_RESOURCES == status)
15174 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15176 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015177 status = -EBUSY;
15178 } else {
15179 status = -EIO;
15180 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015181 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015182
15183#ifdef FEATURE_WLAN_TDLS
15184 wlan_hdd_tdls_scan_done_callback(pAdapter);
15185#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015186 goto free_mem;
15187 }
15188
15189 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015190 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015191 pAdapter->request = request;
15192 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015193 pScanInfo->no_cck = request->no_cck;
15194 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15195 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15196 pHddCtx->scan_info.last_scan_channelList[i] =
15197 request->channels[i]->hw_value;
15198 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015199
15200 complete(&pScanInfo->scan_req_completion_event);
15201
15202free_mem:
15203 if( scanRequest.SSIDs.SSIDList )
15204 {
15205 vos_mem_free(scanRequest.SSIDs.SSIDList);
15206 }
15207
15208 if( channelList )
15209 vos_mem_free( channelList );
15210
15211 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015212 return status;
15213}
15214
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015215int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15216#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15217 struct net_device *dev,
15218#endif
15219 struct cfg80211_scan_request *request)
15220{
15221 int ret;
15222
15223 vos_ssr_protect(__func__);
15224 ret = __wlan_hdd_cfg80211_scan(wiphy,
15225#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15226 dev,
15227#endif
15228 request);
15229 vos_ssr_unprotect(__func__);
15230
15231 return ret;
15232}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015233
15234void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15235{
15236 v_U8_t iniDot11Mode =
15237 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15238 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15239
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015240 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15241 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015242 switch ( iniDot11Mode )
15243 {
15244 case eHDD_DOT11_MODE_AUTO:
15245 case eHDD_DOT11_MODE_11ac:
15246 case eHDD_DOT11_MODE_11ac_ONLY:
15247#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015248 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15249 sme_IsFeatureSupportedByFW(DOT11AC) )
15250 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15251 else
15252 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015253#else
15254 hddDot11Mode = eHDD_DOT11_MODE_11n;
15255#endif
15256 break;
15257 case eHDD_DOT11_MODE_11n:
15258 case eHDD_DOT11_MODE_11n_ONLY:
15259 hddDot11Mode = eHDD_DOT11_MODE_11n;
15260 break;
15261 default:
15262 hddDot11Mode = iniDot11Mode;
15263 break;
15264 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015265#ifdef WLAN_FEATURE_AP_HT40_24G
15266 if (operationChannel > SIR_11B_CHANNEL_END)
15267#endif
15268 {
15269 /* This call decides required channel bonding mode */
15270 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015271 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015272 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015273 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015274}
15275
Jeff Johnson295189b2012-06-20 16:38:30 -070015276/*
15277 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015278 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015279 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015280int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015281 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15282 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015283{
15284 int status = 0;
15285 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015286 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015287 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015288 v_U32_t roamId;
15289 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 eCsrAuthType RSNAuthType;
15291
15292 ENTER();
15293
15294 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015295 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015296 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015297
15298 status = wlan_hdd_validate_context(pHddCtx);
15299 if (status)
15300 {
Yue Mae36e3552014-03-05 17:06:20 -080015301 return status;
15302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015303
Jeff Johnson295189b2012-06-20 16:38:30 -070015304 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15305 {
15306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15307 return -EINVAL;
15308 }
15309
Nitesh Shah9b066282017-06-06 18:05:52 +053015310 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15311
Jeff Johnson295189b2012-06-20 16:38:30 -070015312 pRoamProfile = &pWextState->roamProfile;
15313
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015314 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015315 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015316 hdd_station_ctx_t *pHddStaCtx;
15317 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015318 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015319
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015320 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15321
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015322 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015323 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15324 {
15325 /*QoS not enabled in cfg file*/
15326 pRoamProfile->uapsd_mask = 0;
15327 }
15328 else
15329 {
15330 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015331 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015332 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15333 }
15334
15335 pRoamProfile->SSIDs.numOfSSIDs = 1;
15336 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15337 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015338 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15340 ssid, ssid_len);
15341
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015342 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15343 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15344
Jeff Johnson295189b2012-06-20 16:38:30 -070015345 if (bssid)
15346 {
15347 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015348 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015349 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015350 /* Save BSSID in seperate variable as well, as RoamProfile
15351 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015352 case of join failure we should send valid BSSID to supplicant
15353 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015354 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015355 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015356
Jeff Johnson295189b2012-06-20 16:38:30 -070015357 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015358 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015359 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015360 /* Store bssid_hint to use in the scan filter. */
15361 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15362 WNI_CFG_BSSID_LEN);
15363 /*
15364 * Save BSSID in seperate variable as well, as RoamProfile
15365 * BSSID is getting zeroed out in the association process. And in
15366 * case of join failure we should send valid BSSID to supplicant
15367 */
15368 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15369 WNI_CFG_BSSID_LEN);
15370 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15371 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015372 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015373
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015374
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015375 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15376 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015377 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15378 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015379 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015380 /*set gen ie*/
15381 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15382 /*set auth*/
15383 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015385#ifdef FEATURE_WLAN_WAPI
15386 if (pAdapter->wapi_info.nWapiMode)
15387 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015388 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015389 switch (pAdapter->wapi_info.wapiAuthMode)
15390 {
15391 case WAPI_AUTH_MODE_PSK:
15392 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015393 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 pAdapter->wapi_info.wapiAuthMode);
15395 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15396 break;
15397 }
15398 case WAPI_AUTH_MODE_CERT:
15399 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015400 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015401 pAdapter->wapi_info.wapiAuthMode);
15402 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15403 break;
15404 }
15405 } // End of switch
15406 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15407 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15408 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015409 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015410 pRoamProfile->AuthType.numEntries = 1;
15411 pRoamProfile->EncryptionType.numEntries = 1;
15412 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15413 pRoamProfile->mcEncryptionType.numEntries = 1;
15414 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15415 }
15416 }
15417#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015418#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015419 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015420 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15421 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15422 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015423 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15424 sizeof (tSirGtkOffloadParams));
15425 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015426 }
15427#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015428 pRoamProfile->csrPersona = pAdapter->device_mode;
15429
Jeff Johnson32d95a32012-09-10 13:15:23 -070015430 if( operatingChannel )
15431 {
15432 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15433 pRoamProfile->ChannelInfo.numOfChannels = 1;
15434 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015435 else
15436 {
15437 pRoamProfile->ChannelInfo.ChannelList = NULL;
15438 pRoamProfile->ChannelInfo.numOfChannels = 0;
15439 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015440 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15441 {
15442 hdd_select_cbmode(pAdapter,operatingChannel);
15443 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015444
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015445 /*
15446 * Change conn_state to connecting before sme_RoamConnect(),
15447 * because sme_RoamConnect() has a direct path to call
15448 * hdd_smeRoamCallback(), which will change the conn_state
15449 * If direct path, conn_state will be accordingly changed
15450 * to NotConnected or Associated by either
15451 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15452 * in sme_RoamCallback()
15453 * if sme_RomConnect is to be queued,
15454 * Connecting state will remain until it is completed.
15455 * If connection state is not changed,
15456 * connection state will remain in eConnectionState_NotConnected state.
15457 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15458 * if conn state is eConnectionState_NotConnected.
15459 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15460 * informed of connect result indication which is an issue.
15461 */
15462
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015463 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15464 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015465 {
15466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015467 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015468 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15469 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015470 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015471 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015472 pAdapter->sessionId, pRoamProfile, &roamId);
15473
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015474 if ((eHAL_STATUS_SUCCESS != status) &&
15475 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15476 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015477
15478 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015479 hddLog(VOS_TRACE_LEVEL_ERROR,
15480 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15481 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015482 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015483 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015484 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015485 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015486
15487 pRoamProfile->ChannelInfo.ChannelList = NULL;
15488 pRoamProfile->ChannelInfo.numOfChannels = 0;
15489
Jeff Johnson295189b2012-06-20 16:38:30 -070015490 }
15491 else
15492 {
15493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15494 return -EINVAL;
15495 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015496 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015497 return status;
15498}
15499
15500/*
15501 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15502 * This function is used to set the authentication type (OPEN/SHARED).
15503 *
15504 */
15505static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15506 enum nl80211_auth_type auth_type)
15507{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015508 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015509 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15510
15511 ENTER();
15512
15513 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015514 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015515 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015516 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015517 hddLog(VOS_TRACE_LEVEL_INFO,
15518 "%s: set authentication type to AUTOSWITCH", __func__);
15519 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15520 break;
15521
15522 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015523#ifdef WLAN_FEATURE_VOWIFI_11R
15524 case NL80211_AUTHTYPE_FT:
15525#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015526 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 "%s: set authentication type to OPEN", __func__);
15528 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15529 break;
15530
15531 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015532 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015533 "%s: set authentication type to SHARED", __func__);
15534 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15535 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015536#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015537 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015538 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015539 "%s: set authentication type to CCKM WPA", __func__);
15540 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15541 break;
15542#endif
15543
15544
15545 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015546 hddLog(VOS_TRACE_LEVEL_ERROR,
15547 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015548 auth_type);
15549 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15550 return -EINVAL;
15551 }
15552
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015553 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015554 pHddStaCtx->conn_info.authType;
15555 return 0;
15556}
15557
15558/*
15559 * FUNCTION: wlan_hdd_set_akm_suite
15560 * This function is used to set the key mgmt type(PSK/8021x).
15561 *
15562 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015563static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015564 u32 key_mgmt
15565 )
15566{
15567 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15568 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015569 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015570#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015571#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015572#endif
15573#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015574#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015575#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015576 /*set key mgmt type*/
15577 switch(key_mgmt)
15578 {
15579 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015580 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015581#ifdef WLAN_FEATURE_VOWIFI_11R
15582 case WLAN_AKM_SUITE_FT_PSK:
15583#endif
15584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015585 __func__);
15586 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15587 break;
15588
15589 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015590 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015591#ifdef WLAN_FEATURE_VOWIFI_11R
15592 case WLAN_AKM_SUITE_FT_8021X:
15593#endif
15594 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015595 __func__);
15596 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15597 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015598#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015599#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15600#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15601 case WLAN_AKM_SUITE_CCKM:
15602 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15603 __func__);
15604 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15605 break;
15606#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015607#ifndef WLAN_AKM_SUITE_OSEN
15608#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15609 case WLAN_AKM_SUITE_OSEN:
15610 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15611 __func__);
15612 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15613 break;
15614#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015615
15616 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015618 __func__, key_mgmt);
15619 return -EINVAL;
15620
15621 }
15622 return 0;
15623}
15624
15625/*
15626 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015627 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015628 * (NONE/WEP40/WEP104/TKIP/CCMP).
15629 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015630static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15631 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015632 bool ucast
15633 )
15634{
15635 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015636 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015637 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15638
15639 ENTER();
15640
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015641 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015642 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015644 __func__, cipher);
15645 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15646 }
15647 else
15648 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015649
Jeff Johnson295189b2012-06-20 16:38:30 -070015650 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015651 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015652 {
15653 case IW_AUTH_CIPHER_NONE:
15654 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15655 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015656
Jeff Johnson295189b2012-06-20 16:38:30 -070015657 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015658 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015660
Jeff Johnson295189b2012-06-20 16:38:30 -070015661 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015662 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015663 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015664
Jeff Johnson295189b2012-06-20 16:38:30 -070015665 case WLAN_CIPHER_SUITE_TKIP:
15666 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15667 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015668
Jeff Johnson295189b2012-06-20 16:38:30 -070015669 case WLAN_CIPHER_SUITE_CCMP:
15670 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15671 break;
15672#ifdef FEATURE_WLAN_WAPI
15673 case WLAN_CIPHER_SUITE_SMS4:
15674 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15675 break;
15676#endif
15677
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015678#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015679 case WLAN_CIPHER_SUITE_KRK:
15680 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15681 break;
15682#endif
15683 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015684 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015685 __func__, cipher);
15686 return -EOPNOTSUPP;
15687 }
15688 }
15689
15690 if (ucast)
15691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015692 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015693 __func__, encryptionType);
15694 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15695 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015696 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015697 encryptionType;
15698 }
15699 else
15700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015702 __func__, encryptionType);
15703 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15704 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15705 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15706 }
15707
15708 return 0;
15709}
15710
15711
15712/*
15713 * FUNCTION: wlan_hdd_cfg80211_set_ie
15714 * This function is used to parse WPA/RSN IE's.
15715 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015716int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15718 const u8 *ie,
15719#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015720 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015721#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015722 size_t ie_len
15723 )
15724{
15725 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015726#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15727 const u8 *genie = ie;
15728#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015729 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015730#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015731 v_U16_t remLen = ie_len;
15732#ifdef FEATURE_WLAN_WAPI
15733 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15734 u16 *tmp;
15735 v_U16_t akmsuiteCount;
15736 int *akmlist;
15737#endif
15738 ENTER();
15739
15740 /* clear previous assocAddIE */
15741 pWextState->assocAddIE.length = 0;
15742 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015743 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015744
15745 while (remLen >= 2)
15746 {
15747 v_U16_t eLen = 0;
15748 v_U8_t elementId;
15749 elementId = *genie++;
15750 eLen = *genie++;
15751 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015752
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015753 /* Sanity check on eLen */
15754 if (eLen > remLen) {
15755 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15756 __func__, eLen, elementId);
15757 VOS_ASSERT(0);
15758 return -EINVAL;
15759 }
15760
Arif Hussain6d2a3322013-11-17 19:50:10 -080015761 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015762 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015763
15764 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015765 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015766 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015767 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 -070015768 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015769 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015770 "%s: Invalid WPA IE", __func__);
15771 return -EINVAL;
15772 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015773 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015774 {
15775 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015776 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015777 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015778
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015779 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015780 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015781 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15782 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015783 VOS_ASSERT(0);
15784 return -ENOMEM;
15785 }
15786 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15787 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15788 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015789
Jeff Johnson295189b2012-06-20 16:38:30 -070015790 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15791 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15792 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15793 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015794 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15795 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015796 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15797 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15798 __func__, eLen);
15799 VOS_ASSERT(0);
15800 return -EINVAL;
15801 }
15802
Jeff Johnson295189b2012-06-20 16:38:30 -070015803 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15804 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15805 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15806 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15807 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15808 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015809 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015810 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015811 {
15812 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015813 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015814 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015815
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015816 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015818 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15819 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015820 VOS_ASSERT(0);
15821 return -ENOMEM;
15822 }
15823 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15824 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15825 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015826
Jeff Johnson295189b2012-06-20 16:38:30 -070015827 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15828 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15829 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015830#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015831 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15832 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015833 /*Consider WFD IE, only for P2P Client */
15834 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15835 {
15836 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015837 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015838 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015839
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015840 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015841 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015842 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15843 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015844 VOS_ASSERT(0);
15845 return -ENOMEM;
15846 }
15847 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15848 // WPS IE + P2P IE + WFD IE
15849 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15850 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015851
Jeff Johnson295189b2012-06-20 16:38:30 -070015852 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15853 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15854 }
15855#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015856 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015857 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015858 HS20_OUI_TYPE_SIZE)) )
15859 {
15860 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015861 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015862 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015863
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015864 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015865 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015866 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15867 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015868 VOS_ASSERT(0);
15869 return -ENOMEM;
15870 }
15871 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15872 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015873
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015874 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15875 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15876 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015877 /* Appending OSEN Information Element in Assiciation Request */
15878 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15879 OSEN_OUI_TYPE_SIZE)) )
15880 {
15881 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15882 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15883 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015884
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015885 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015886 {
15887 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15888 "Need bigger buffer space");
15889 VOS_ASSERT(0);
15890 return -ENOMEM;
15891 }
15892 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15893 pWextState->assocAddIE.length += eLen + 2;
15894
15895 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15896 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15897 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15898 }
15899
Abhishek Singh4322e622015-06-10 15:42:54 +053015900 /* Update only for WPA IE */
15901 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15902 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015903
15904 /* populating as ADDIE in beacon frames */
15905 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015906 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015907 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15908 {
15909 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15910 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15912 {
15913 hddLog(LOGE,
15914 "Coldn't pass "
15915 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15916 }
15917 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15918 else
15919 hddLog(LOGE,
15920 "Could not pass on "
15921 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15922
15923 /* IBSS mode doesn't contain params->proberesp_ies still
15924 beaconIE's need to be populated in probe response frames */
15925 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15926 {
15927 u16 rem_probe_resp_ie_len = eLen + 2;
15928 u8 probe_rsp_ie_len[3] = {0};
15929 u8 counter = 0;
15930
15931 /* Check Probe Resp Length if it is greater then 255 then
15932 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15933 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15934 not able Store More then 255 bytes into One Variable */
15935
15936 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15937 {
15938 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15939 {
15940 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15941 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15942 }
15943 else
15944 {
15945 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15946 rem_probe_resp_ie_len = 0;
15947 }
15948 }
15949
15950 rem_probe_resp_ie_len = 0;
15951
15952 if (probe_rsp_ie_len[0] > 0)
15953 {
15954 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15955 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15956 (tANI_U8*)(genie - 2),
15957 probe_rsp_ie_len[0], NULL,
15958 eANI_BOOLEAN_FALSE)
15959 == eHAL_STATUS_FAILURE)
15960 {
15961 hddLog(LOGE,
15962 "Could not pass"
15963 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15964 }
15965 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15966 }
15967
15968 if (probe_rsp_ie_len[1] > 0)
15969 {
15970 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15971 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15972 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15973 probe_rsp_ie_len[1], NULL,
15974 eANI_BOOLEAN_FALSE)
15975 == eHAL_STATUS_FAILURE)
15976 {
15977 hddLog(LOGE,
15978 "Could not pass"
15979 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15980 }
15981 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15982 }
15983
15984 if (probe_rsp_ie_len[2] > 0)
15985 {
15986 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15987 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15988 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15989 probe_rsp_ie_len[2], NULL,
15990 eANI_BOOLEAN_FALSE)
15991 == eHAL_STATUS_FAILURE)
15992 {
15993 hddLog(LOGE,
15994 "Could not pass"
15995 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15996 }
15997 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15998 }
15999
16000 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16001 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16002 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16003 {
16004 hddLog(LOGE,
16005 "Could not pass"
16006 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16007 }
16008 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016009 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016010 break;
16011 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016012 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16013 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16014 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16015 VOS_ASSERT(0);
16016 return -EINVAL;
16017 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16019 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16020 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16021 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16022 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16023 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016024
Abhishek Singhb16f3562016-01-20 11:08:32 +053016025 /* Appending extended capabilities with Interworking or
16026 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016027 *
16028 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016029 * interworkingService or bsstransition bit is set to 1.
16030 * Driver is only interested in interworkingService and
16031 * bsstransition capability from supplicant.
16032 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016033 * required from supplicat, it needs to be handled while
16034 * sending Assoc Req in LIM.
16035 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016036 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016037 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016038 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016039 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016040 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016041
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016042 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016043 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016044 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16045 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016046 VOS_ASSERT(0);
16047 return -ENOMEM;
16048 }
16049 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16050 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016051
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016052 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16053 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16054 break;
16055 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016056#ifdef FEATURE_WLAN_WAPI
16057 case WLAN_EID_WAPI:
16058 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016059 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 pAdapter->wapi_info.nWapiMode);
16061 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016062 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 akmsuiteCount = WPA_GET_LE16(tmp);
16064 tmp = tmp + 1;
16065 akmlist = (int *)(tmp);
16066 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16067 {
16068 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16069 }
16070 else
16071 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016072 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016073 VOS_ASSERT(0);
16074 return -EINVAL;
16075 }
16076
16077 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16078 {
16079 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016080 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016081 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016083 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016084 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016086 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16088 }
16089 break;
16090#endif
16091 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016092 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016093 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016094 /* when Unknown IE is received we should break and continue
16095 * to the next IE in the buffer instead we were returning
16096 * so changing this to break */
16097 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016098 }
16099 genie += eLen;
16100 remLen -= eLen;
16101 }
16102 EXIT();
16103 return 0;
16104}
16105
16106/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016107 * FUNCTION: hdd_isWPAIEPresent
16108 * Parse the received IE to find the WPA IE
16109 *
16110 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016111static bool hdd_isWPAIEPresent(
16112#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16113 const u8 *ie,
16114#else
16115 u8 *ie,
16116#endif
16117 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016118{
16119 v_U8_t eLen = 0;
16120 v_U16_t remLen = ie_len;
16121 v_U8_t elementId = 0;
16122
16123 while (remLen >= 2)
16124 {
16125 elementId = *ie++;
16126 eLen = *ie++;
16127 remLen -= 2;
16128 if (eLen > remLen)
16129 {
16130 hddLog(VOS_TRACE_LEVEL_ERROR,
16131 "%s: IE length is wrong %d", __func__, eLen);
16132 return FALSE;
16133 }
16134 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16135 {
16136 /* OUI - 0x00 0X50 0XF2
16137 WPA Information Element - 0x01
16138 WPA version - 0x01*/
16139 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16140 return TRUE;
16141 }
16142 ie += eLen;
16143 remLen -= eLen;
16144 }
16145 return FALSE;
16146}
16147
16148/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016149 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016150 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016151 * parameters during connect operation.
16152 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016153int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016154 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016155 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016156{
16157 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016158 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016159 ENTER();
16160
16161 /*set wpa version*/
16162 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16163
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016164 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016165 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016166 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016167 {
16168 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16169 }
16170 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16171 {
16172 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16173 }
16174 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016175
16176 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016177 pWextState->wpaVersion);
16178
16179 /*set authentication type*/
16180 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16181
16182 if (0 > status)
16183 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016184 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 "%s: failed to set authentication type ", __func__);
16186 return status;
16187 }
16188
16189 /*set key mgmt type*/
16190 if (req->crypto.n_akm_suites)
16191 {
16192 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16193 if (0 > status)
16194 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016196 __func__);
16197 return status;
16198 }
16199 }
16200
16201 /*set pairwise cipher type*/
16202 if (req->crypto.n_ciphers_pairwise)
16203 {
16204 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16205 req->crypto.ciphers_pairwise[0], true);
16206 if (0 > status)
16207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016208 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016209 "%s: failed to set unicast cipher type", __func__);
16210 return status;
16211 }
16212 }
16213 else
16214 {
16215 /*Reset previous cipher suite to none*/
16216 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16217 if (0 > status)
16218 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016219 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016220 "%s: failed to set unicast cipher type", __func__);
16221 return status;
16222 }
16223 }
16224
16225 /*set group cipher type*/
16226 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16227 false);
16228
16229 if (0 > status)
16230 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016232 __func__);
16233 return status;
16234 }
16235
Chet Lanctot186b5732013-03-18 10:26:30 -070016236#ifdef WLAN_FEATURE_11W
16237 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16238#endif
16239
Jeff Johnson295189b2012-06-20 16:38:30 -070016240 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16241 if (req->ie_len)
16242 {
16243 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16244 if ( 0 > status)
16245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016247 __func__);
16248 return status;
16249 }
16250 }
16251
16252 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016253 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016254 {
16255 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16256 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16257 )
16258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016259 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016260 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016263 __func__);
16264 return -EOPNOTSUPP;
16265 }
16266 else
16267 {
16268 u8 key_len = req->key_len;
16269 u8 key_idx = req->key_idx;
16270
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016271 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016272 && (CSR_MAX_NUM_KEY > key_idx)
16273 )
16274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016275 hddLog(VOS_TRACE_LEVEL_INFO,
16276 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016277 __func__, key_idx, key_len);
16278 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016279 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016280 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016281 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016282 (u8)key_len;
16283 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16284 }
16285 }
16286 }
16287 }
16288
16289 return status;
16290}
16291
16292/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016293 * FUNCTION: wlan_hdd_try_disconnect
16294 * This function is used to disconnect from previous
16295 * connection
16296 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016297int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016298{
16299 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016300 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016301 hdd_station_ctx_t *pHddStaCtx;
16302 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016303 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016304
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016305 ret = wlan_hdd_validate_context(pHddCtx);
16306 if (0 != ret)
16307 {
16308 return ret;
16309 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016310 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16311
16312 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16313
16314 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16315 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016316 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016317 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16318 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016319 /* Indicate disconnect to SME so that in-progress connection or preauth
16320 * can be aborted
16321 */
16322 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16323 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016324 spin_lock_bh(&pAdapter->lock_for_active_session);
16325 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16326 {
16327 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16328 }
16329 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016330 hdd_connSetConnectionState(pHddStaCtx,
16331 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016332 /* Issue disconnect to CSR */
16333 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016334 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016335 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016336 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16337 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16338 hddLog(LOG1,
16339 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16340 } else if ( 0 != status ) {
16341 hddLog(LOGE,
16342 FL("csrRoamDisconnect failure, returned %d"),
16343 (int)status );
16344 result = -EINVAL;
16345 goto disconnected;
16346 }
16347 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016348 &pAdapter->disconnect_comp_var,
16349 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016350 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16351 hddLog(LOGE,
16352 "%s: Failed to disconnect, timed out", __func__);
16353 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016354 }
16355 }
16356 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16357 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016358 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016359 &pAdapter->disconnect_comp_var,
16360 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016361 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016362 {
16363 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016364 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016365 }
16366 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016367disconnected:
16368 hddLog(LOG1,
16369 FL("Set HDD connState to eConnectionState_NotConnected"));
16370 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16371 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016372}
16373
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016374/**
16375 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16376 * @adapter: Pointer to the HDD adapter
16377 * @req: Pointer to the structure cfg_connect_params receieved from user space
16378 *
16379 * This function will start reassociation if bssid hint, channel hint and
16380 * previous bssid parameters are present in the connect request
16381 *
16382 * Return: success if reassociation is happening
16383 * Error code if reassociation is not permitted or not happening
16384 */
16385#ifdef CFG80211_CONNECT_PREV_BSSID
16386static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16387 struct cfg80211_connect_params *req)
16388{
16389 int status = -EPERM;
16390 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16391 hddLog(VOS_TRACE_LEVEL_INFO,
16392 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16393 req->channel_hint->hw_value,
16394 MAC_ADDR_ARRAY(req->bssid_hint));
16395 status = hdd_reassoc(adapter, req->bssid_hint,
16396 req->channel_hint->hw_value,
16397 CONNECT_CMD_USERSPACE);
16398 }
16399 return status;
16400}
16401#else
16402static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16403 struct cfg80211_connect_params *req)
16404{
16405 return -EPERM;
16406}
16407#endif
16408
Abhishek Singhe3beee22017-07-31 15:35:40 +053016409/**
16410 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16411 * connect in HT20 mode
16412 * @hdd_ctx: hdd context
16413 * @adapter: Pointer to the HDD adapter
16414 * @req: Pointer to the structure cfg_connect_params receieved from user space
16415 *
16416 * This function will check if supplicant has indicated to to connect in HT20
16417 * mode. this is currently applicable only for 2.4Ghz mode only.
16418 * if feature is enabled and supplicant indicate HT20 set
16419 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16420 *
16421 * Return: void
16422 */
16423#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16424static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16425 hdd_adapter_t *adapter,
16426 struct cfg80211_connect_params *req)
16427{
16428 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16429 tCsrRoamProfile *roam_profile;
16430
16431 roam_profile = &wext_state->roamProfile;
16432 roam_profile->force_24ghz_in_ht20 = false;
16433 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16434 !(req->ht_capa.cap_info &
16435 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16436 roam_profile->force_24ghz_in_ht20 = true;
16437
16438 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16439 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16440}
16441#else
16442static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16443 hdd_adapter_t *adapter,
16444 struct cfg80211_connect_params *req)
16445{
16446 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16447 tCsrRoamProfile *roam_profile;
16448
16449 roam_profile = &wext_state->roamProfile;
16450 roam_profile->force_24ghz_in_ht20 = false;
16451}
16452#endif
16453
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016454/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016455 * FUNCTION: __wlan_hdd_cfg80211_connect
16456 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016457 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016458static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016459 struct net_device *ndev,
16460 struct cfg80211_connect_params *req
16461 )
16462{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016463 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016464 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016465#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16466 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016467 const u8 *bssid_hint = req->bssid_hint;
16468#else
16469 const u8 *bssid_hint = NULL;
16470#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016472 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016473 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016474
16475 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16478 TRACE_CODE_HDD_CFG80211_CONNECT,
16479 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016480 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016481 "%s: device_mode = %s (%d)", __func__,
16482 hdd_device_modetoString(pAdapter->device_mode),
16483 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016484
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016485 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016486 if (!pHddCtx)
16487 {
16488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16489 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016490 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016491 }
16492
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016493 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016494 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016495 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016496 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016497 }
16498
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016499 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16500 return -EINVAL;
16501
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016502 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16503 if (0 == status)
16504 return status;
16505
Agarwal Ashish51325b52014-06-16 16:50:49 +053016506
Jeff Johnson295189b2012-06-20 16:38:30 -070016507#ifdef WLAN_BTAMP_FEATURE
16508 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016509 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016511 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016512 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016513 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016514 }
16515#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016516
16517 //If Device Mode is Station Concurrent Sessions Exit BMps
16518 //P2P Mode will be taken care in Open/close adapter
16519 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016520 (vos_concurrent_open_sessions_running())) {
16521 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16522 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016523 }
16524
16525 /*Try disconnecting if already in connected state*/
16526 status = wlan_hdd_try_disconnect(pAdapter);
16527 if ( 0 > status)
16528 {
16529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16530 " connection"));
16531 return -EALREADY;
16532 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016533 /* Check for max concurrent connections after doing disconnect if any*/
16534 if (vos_max_concurrent_connections_reached()) {
16535 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16536 return -ECONNREFUSED;
16537 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016538
Jeff Johnson295189b2012-06-20 16:38:30 -070016539 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016540 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016541
16542 if ( 0 > status)
16543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016545 __func__);
16546 return status;
16547 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016548
16549 if (pHddCtx->spoofMacAddr.isEnabled)
16550 {
16551 hddLog(VOS_TRACE_LEVEL_INFO,
16552 "%s: MAC Spoofing enabled ", __func__);
16553 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16554 * to fill TxBds for probe request during SSID scan which may happen
16555 * as part of connect command
16556 */
16557 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16558 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16559 if (status != VOS_STATUS_SUCCESS)
16560 return -ECONNREFUSED;
16561 }
16562
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016563 if (req->channel)
16564 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016565 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016566 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016567
16568 /* Abort if any scan is going on */
16569 status = wlan_hdd_scan_abort(pAdapter);
16570 if (0 != status)
16571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16572
Abhishek Singhe3beee22017-07-31 15:35:40 +053016573 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16574
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016575 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16576 req->ssid_len, req->bssid,
16577 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016578
Sushant Kaushikd7083982015-03-18 14:33:24 +053016579 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 {
16581 //ReEnable BMPS if disabled
16582 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16583 (NULL != pHddCtx))
16584 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016585 if (pHddCtx->hdd_wlan_suspended)
16586 {
16587 hdd_set_pwrparams(pHddCtx);
16588 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016589 //ReEnable Bmps and Imps back
16590 hdd_enable_bmps_imps(pHddCtx);
16591 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016593 return status;
16594 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016595 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016596 EXIT();
16597 return status;
16598}
16599
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016600static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16601 struct net_device *ndev,
16602 struct cfg80211_connect_params *req)
16603{
16604 int ret;
16605 vos_ssr_protect(__func__);
16606 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16607 vos_ssr_unprotect(__func__);
16608
16609 return ret;
16610}
Jeff Johnson295189b2012-06-20 16:38:30 -070016611
16612/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016613 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016614 * This function is used to issue a disconnect request to SME
16615 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016616static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016617 struct net_device *dev,
16618 u16 reason
16619 )
16620{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016622 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016623 tCsrRoamProfile *pRoamProfile;
16624 hdd_station_ctx_t *pHddStaCtx;
16625 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016626#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016627 tANI_U8 staIdx;
16628#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016629
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016631
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016632 if (!pAdapter) {
16633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16634 return -EINVAL;
16635 }
16636
16637 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16638 if (!pHddStaCtx) {
16639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16640 return -EINVAL;
16641 }
16642
16643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16644 status = wlan_hdd_validate_context(pHddCtx);
16645 if (0 != status)
16646 {
16647 return status;
16648 }
16649
16650 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16651
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016652 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16653 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16654 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016655 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16656 __func__, hdd_device_modetoString(pAdapter->device_mode),
16657 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016658
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016659 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16660 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016661
Jeff Johnson295189b2012-06-20 16:38:30 -070016662 if (NULL != pRoamProfile)
16663 {
16664 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016665 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16666 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016667 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016668 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016669 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016670 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016671 switch(reason)
16672 {
16673 case WLAN_REASON_MIC_FAILURE:
16674 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16675 break;
16676
16677 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16678 case WLAN_REASON_DISASSOC_AP_BUSY:
16679 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16680 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16681 break;
16682
16683 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16684 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016685 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016686 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16687 break;
16688
Jeff Johnson295189b2012-06-20 16:38:30 -070016689 default:
16690 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16691 break;
16692 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016693 pScanInfo = &pHddCtx->scan_info;
16694 if (pScanInfo->mScanPending)
16695 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016696 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016697 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016698 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016699 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016700 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016701 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016702#ifdef FEATURE_WLAN_TDLS
16703 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016704 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016705 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016706 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16707 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016708 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016709 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016710 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016712 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016713 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016714 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016715 status = sme_DeleteTdlsPeerSta(
16716 WLAN_HDD_GET_HAL_CTX(pAdapter),
16717 pAdapter->sessionId,
16718 mac);
16719 if (status != eHAL_STATUS_SUCCESS) {
16720 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16721 return -EPERM;
16722 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016723 }
16724 }
16725#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016726
16727 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16728 reasonCode,
16729 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016730 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16731 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016732 {
16733 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016734 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 __func__, (int)status );
16736 return -EINVAL;
16737 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016738 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016739 else
16740 {
16741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16742 "called while in %d state", __func__,
16743 pHddStaCtx->conn_info.connState);
16744 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016745 }
16746 else
16747 {
16748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16749 }
16750
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016751 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016752 return status;
16753}
16754
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016755static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16756 struct net_device *dev,
16757 u16 reason
16758 )
16759{
16760 int ret;
16761 vos_ssr_protect(__func__);
16762 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16763 vos_ssr_unprotect(__func__);
16764
16765 return ret;
16766}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016767
Jeff Johnson295189b2012-06-20 16:38:30 -070016768/*
16769 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016770 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016771 * settings in IBSS mode.
16772 */
16773static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016774 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016775 struct cfg80211_ibss_params *params
16776 )
16777{
16778 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016779 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016780 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16781 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016782
Jeff Johnson295189b2012-06-20 16:38:30 -070016783 ENTER();
16784
16785 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016786 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016787
16788 if (params->ie_len && ( NULL != params->ie) )
16789 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016790 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16791 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 {
16793 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16794 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16795 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016796 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016797 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016798 tDot11fIEWPA dot11WPAIE;
16799 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016800 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016801
Wilson Yang00256342013-10-10 23:13:38 -070016802 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016803 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16804 params->ie_len, DOT11F_EID_WPA);
16805 if ( NULL != ie )
16806 {
16807 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16808 // Unpack the WPA IE
16809 //Skip past the EID byte and length byte - and four byte WiFi OUI
16810 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16811 &ie[2+4],
16812 ie[1] - 4,
16813 &dot11WPAIE);
16814 /*Extract the multicast cipher, the encType for unicast
16815 cipher for wpa-none is none*/
16816 encryptionType =
16817 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16818 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016819 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016820
Jeff Johnson295189b2012-06-20 16:38:30 -070016821 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16822
16823 if (0 > status)
16824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016826 __func__);
16827 return status;
16828 }
16829 }
16830
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016831 pWextState->roamProfile.AuthType.authType[0] =
16832 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016833 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070016834 if (params->privacy)
16835 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016836 /* Security enabled IBSS, At this time there is no information available
16837 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016838 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016839 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016840 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016841 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016842 *enable privacy bit in beacons */
16843
16844 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16845 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016846 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16847 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016848 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16849 pWextState->roamProfile.EncryptionType.numEntries = 1;
16850 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016851 return status;
16852}
16853
16854/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016855 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016856 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016857 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016858static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016859 struct net_device *dev,
16860 struct cfg80211_ibss_params *params
16861 )
16862{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016863 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016864 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16865 tCsrRoamProfile *pRoamProfile;
16866 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016867 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16868 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016869 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016870
16871 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016872
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016873 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16874 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16875 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016876 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016877 "%s: device_mode = %s (%d)", __func__,
16878 hdd_device_modetoString(pAdapter->device_mode),
16879 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016881 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016882 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016883 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016884 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016885 }
16886
16887 if (NULL == pWextState)
16888 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016889 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016890 __func__);
16891 return -EIO;
16892 }
16893
Agarwal Ashish51325b52014-06-16 16:50:49 +053016894 if (vos_max_concurrent_connections_reached()) {
16895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16896 return -ECONNREFUSED;
16897 }
16898
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016899 /*Try disconnecting if already in connected state*/
16900 status = wlan_hdd_try_disconnect(pAdapter);
16901 if ( 0 > status)
16902 {
16903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16904 " IBSS connection"));
16905 return -EALREADY;
16906 }
16907
Jeff Johnson295189b2012-06-20 16:38:30 -070016908 pRoamProfile = &pWextState->roamProfile;
16909
16910 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16911 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016912 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016913 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016914 return -EINVAL;
16915 }
16916
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016917 /* BSSID is provided by upper layers hence no need to AUTO generate */
16918 if (NULL != params->bssid) {
16919 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16920 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16921 hddLog (VOS_TRACE_LEVEL_ERROR,
16922 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16923 return -EIO;
16924 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016925 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016926 }
krunal sonie9002db2013-11-25 14:24:17 -080016927 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16928 {
16929 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16930 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16931 {
16932 hddLog (VOS_TRACE_LEVEL_ERROR,
16933 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16934 return -EIO;
16935 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016936
16937 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016938 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016939 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016940 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016941
Jeff Johnson295189b2012-06-20 16:38:30 -070016942 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016943 if (NULL !=
16944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16945 params->chandef.chan)
16946#else
16947 params->channel)
16948#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016949 {
16950 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016951 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16952 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16953 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16954 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016955
16956 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016957 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016958 ieee80211_frequency_to_channel(
16959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16960 params->chandef.chan->center_freq);
16961#else
16962 params->channel->center_freq);
16963#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016964
16965 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16966 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016967 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16969 __func__);
16970 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016971 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016972
16973 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016974 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016975 if (channelNum == validChan[indx])
16976 {
16977 break;
16978 }
16979 }
16980 if (indx >= numChans)
16981 {
16982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016983 __func__, channelNum);
16984 return -EINVAL;
16985 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016986 /* Set the Operational Channel */
16987 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16988 channelNum);
16989 pRoamProfile->ChannelInfo.numOfChannels = 1;
16990 pHddStaCtx->conn_info.operationChannel = channelNum;
16991 pRoamProfile->ChannelInfo.ChannelList =
16992 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016993 }
16994
16995 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016996 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016997 if (status < 0)
16998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017000 __func__);
17001 return status;
17002 }
17003
17004 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017005 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017006 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017007 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017008
17009 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017010 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017012 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017013 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017014}
17015
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017016static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17017 struct net_device *dev,
17018 struct cfg80211_ibss_params *params
17019 )
17020{
17021 int ret = 0;
17022
17023 vos_ssr_protect(__func__);
17024 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17025 vos_ssr_unprotect(__func__);
17026
17027 return ret;
17028}
17029
Jeff Johnson295189b2012-06-20 16:38:30 -070017030/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017031 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017032 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017033 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017034static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017035 struct net_device *dev
17036 )
17037{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017038 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017039 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17040 tCsrRoamProfile *pRoamProfile;
17041 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017042 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017043 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017044#ifdef WLAN_FEATURE_RMC
17045 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017047
17048 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017049
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017050 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17051 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17052 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017053 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017054 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017056 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017057 }
17058
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17060 hdd_device_modetoString(pAdapter->device_mode),
17061 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017062 if (NULL == pWextState)
17063 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017064 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017065 __func__);
17066 return -EIO;
17067 }
17068
17069 pRoamProfile = &pWextState->roamProfile;
17070
17071 /* Issue disconnect only if interface type is set to IBSS */
17072 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017074 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017075 __func__);
17076 return -EINVAL;
17077 }
17078
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017079#ifdef WLAN_FEATURE_RMC
17080 /* Clearing add IE of beacon */
17081 if (ccmCfgSetStr(pHddCtx->hHal,
17082 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17083 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17084 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17085 {
17086 hddLog (VOS_TRACE_LEVEL_ERROR,
17087 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17088 return -EINVAL;
17089 }
17090 if (ccmCfgSetInt(pHddCtx->hHal,
17091 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17092 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17093 {
17094 hddLog (VOS_TRACE_LEVEL_ERROR,
17095 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17096 __func__);
17097 return -EINVAL;
17098 }
17099
17100 // Reset WNI_CFG_PROBE_RSP Flags
17101 wlan_hdd_reset_prob_rspies(pAdapter);
17102
17103 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17104 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17105 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17106 {
17107 hddLog (VOS_TRACE_LEVEL_ERROR,
17108 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17109 __func__);
17110 return -EINVAL;
17111 }
17112#endif
17113
Jeff Johnson295189b2012-06-20 16:38:30 -070017114 /* Issue Disconnect request */
17115 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017116 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17117 pAdapter->sessionId,
17118 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17119 if (!HAL_STATUS_SUCCESS(hal_status)) {
17120 hddLog(LOGE,
17121 FL("sme_RoamDisconnect failed hal_status(%d)"),
17122 hal_status);
17123 return -EAGAIN;
17124 }
17125 status = wait_for_completion_timeout(
17126 &pAdapter->disconnect_comp_var,
17127 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17128 if (!status) {
17129 hddLog(LOGE,
17130 FL("wait on disconnect_comp_var failed"));
17131 return -ETIMEDOUT;
17132 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017134 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017135 return 0;
17136}
17137
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017138static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17139 struct net_device *dev
17140 )
17141{
17142 int ret = 0;
17143
17144 vos_ssr_protect(__func__);
17145 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17146 vos_ssr_unprotect(__func__);
17147
17148 return ret;
17149}
17150
Jeff Johnson295189b2012-06-20 16:38:30 -070017151/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017152 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017153 * This function is used to set the phy parameters
17154 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17155 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017156static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017157 u32 changed)
17158{
17159 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17160 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017161 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017162
17163 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017164
17165 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017166 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17167 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017169 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017170 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017172 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017173 }
17174
Jeff Johnson295189b2012-06-20 16:38:30 -070017175 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17176 {
17177 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17178 WNI_CFG_RTS_THRESHOLD_STAMAX :
17179 wiphy->rts_threshold;
17180
17181 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017182 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017183 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017184 hddLog(VOS_TRACE_LEVEL_ERROR,
17185 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017186 __func__, rts_threshold);
17187 return -EINVAL;
17188 }
17189
17190 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17191 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017192 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017194 hddLog(VOS_TRACE_LEVEL_ERROR,
17195 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017196 __func__, rts_threshold);
17197 return -EIO;
17198 }
17199
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017200 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017201 rts_threshold);
17202 }
17203
17204 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17205 {
17206 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17207 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17208 wiphy->frag_threshold;
17209
17210 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017211 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017212 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017213 hddLog(VOS_TRACE_LEVEL_ERROR,
17214 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017215 frag_threshold);
17216 return -EINVAL;
17217 }
17218
17219 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17220 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017221 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017222 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017223 hddLog(VOS_TRACE_LEVEL_ERROR,
17224 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017225 __func__, frag_threshold);
17226 return -EIO;
17227 }
17228
17229 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17230 frag_threshold);
17231 }
17232
17233 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17234 || (changed & WIPHY_PARAM_RETRY_LONG))
17235 {
17236 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17237 wiphy->retry_short :
17238 wiphy->retry_long;
17239
17240 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17241 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17242 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017244 __func__, retry_value);
17245 return -EINVAL;
17246 }
17247
17248 if (changed & WIPHY_PARAM_RETRY_SHORT)
17249 {
17250 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17251 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017252 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017253 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017254 hddLog(VOS_TRACE_LEVEL_ERROR,
17255 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017256 __func__, retry_value);
17257 return -EIO;
17258 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017259 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 __func__, retry_value);
17261 }
17262 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17263 {
17264 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17265 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017266 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017268 hddLog(VOS_TRACE_LEVEL_ERROR,
17269 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017270 __func__, retry_value);
17271 return -EIO;
17272 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017273 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017274 __func__, retry_value);
17275 }
17276 }
17277
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017278 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017279 return 0;
17280}
17281
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017282static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17283 u32 changed)
17284{
17285 int ret;
17286
17287 vos_ssr_protect(__func__);
17288 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17289 vos_ssr_unprotect(__func__);
17290
17291 return ret;
17292}
17293
Jeff Johnson295189b2012-06-20 16:38:30 -070017294/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017295 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017296 * This function is used to set the txpower
17297 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017298static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017299#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17300 struct wireless_dev *wdev,
17301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017302#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017303 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017304#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017305 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017306#endif
17307 int dbm)
17308{
17309 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017310 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017311 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17312 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017313 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017314
17315 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017316
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017317 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17318 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17319 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017320 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017321 if (0 != status)
17322 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017323 return status;
17324 }
17325
17326 hHal = pHddCtx->hHal;
17327
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017328 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17329 dbm, ccmCfgSetCallback,
17330 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017332 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017333 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17334 return -EIO;
17335 }
17336
17337 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17338 dbm);
17339
17340 switch(type)
17341 {
17342 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17343 /* Fall through */
17344 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17345 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17348 __func__);
17349 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017350 }
17351 break;
17352 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017353 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017354 __func__);
17355 return -EOPNOTSUPP;
17356 break;
17357 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17359 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017360 return -EIO;
17361 }
17362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017363 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 return 0;
17365}
17366
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017367static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17368#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17369 struct wireless_dev *wdev,
17370#endif
17371#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17372 enum tx_power_setting type,
17373#else
17374 enum nl80211_tx_power_setting type,
17375#endif
17376 int dbm)
17377{
17378 int ret;
17379 vos_ssr_protect(__func__);
17380 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17381#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17382 wdev,
17383#endif
17384#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17385 type,
17386#else
17387 type,
17388#endif
17389 dbm);
17390 vos_ssr_unprotect(__func__);
17391
17392 return ret;
17393}
17394
Jeff Johnson295189b2012-06-20 16:38:30 -070017395/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017396 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017397 * This function is used to read the txpower
17398 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017399static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017400#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17401 struct wireless_dev *wdev,
17402#endif
17403 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017404{
17405
17406 hdd_adapter_t *pAdapter;
17407 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017408 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017409
Jeff Johnsone7245742012-09-05 17:12:55 -070017410 ENTER();
17411
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017412 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017413 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017414 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017415 *dbm = 0;
17416 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017417 }
17418
Jeff Johnson295189b2012-06-20 16:38:30 -070017419 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17420 if (NULL == pAdapter)
17421 {
17422 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17423 return -ENOENT;
17424 }
17425
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017426 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17427 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17428 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017429 wlan_hdd_get_classAstats(pAdapter);
17430 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17431
Jeff Johnsone7245742012-09-05 17:12:55 -070017432 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017433 return 0;
17434}
17435
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017436static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17437#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17438 struct wireless_dev *wdev,
17439#endif
17440 int *dbm)
17441{
17442 int ret;
17443
17444 vos_ssr_protect(__func__);
17445 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17446#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17447 wdev,
17448#endif
17449 dbm);
17450 vos_ssr_unprotect(__func__);
17451
17452 return ret;
17453}
17454
Dustin Brown8c1d4092017-07-28 18:08:01 +053017455/*
17456 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17457 * @stats: summary stats to use as a source
17458 * @info: kernel station_info struct to use as a destination
17459 *
17460 * Return: None
17461 */
17462static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17463 struct station_info *info)
17464{
17465 int i;
17466
17467 info->rx_packets = stats->rx_frm_cnt;
17468 info->tx_packets = 0;
17469 info->tx_retries = 0;
17470 info->tx_failed = 0;
17471
17472 for (i = 0; i < 4; ++i) {
17473 info->tx_packets += stats->tx_frm_cnt[i];
17474 info->tx_retries += stats->multiple_retry_cnt[i];
17475 info->tx_failed += stats->fail_cnt[i];
17476 }
17477
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017478#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17479 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017480 info->filled |= STATION_INFO_TX_PACKETS |
17481 STATION_INFO_TX_RETRIES |
17482 STATION_INFO_TX_FAILED |
17483 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017484#else
17485 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17486 BIT(NL80211_STA_INFO_TX_RETRIES) |
17487 BIT(NL80211_STA_INFO_TX_FAILED) |
17488 BIT(NL80211_STA_INFO_RX_PACKETS);
17489#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017490}
17491
17492/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017493 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17494 * @adapter: sap adapter pointer
17495 * @staid: station id of the client
17496 * @rssi: rssi value to fill
17497 *
17498 * Return: None
17499 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017500void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017501wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17502{
17503 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17504
17505 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17506}
17507
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017508#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17509 !defined(WITH_BACKPORTS)
17510static inline void wlan_hdd_fill_station_info_signal(struct station_info
17511 *sinfo)
17512{
17513 sinfo->filled |= STATION_INFO_SIGNAL;
17514}
17515#else
17516static inline void wlan_hdd_fill_station_info_signal(struct station_info
17517 *sinfo)
17518{
17519 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17520}
17521#endif
17522
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017523/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017524 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17525 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017526 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017527 * @info: kernel station_info struct to populate
17528 *
17529 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17530 * support "station dump" and "station get" for SAP vdevs, even though they
17531 * aren't technically stations.
17532 *
17533 * Return: errno
17534 */
17535static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017536wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17537#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17538 const u8* mac,
17539#else
17540 u8* mac,
17541#endif
17542 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017543{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017544 v_MACADDR_t *peerMacAddr;
17545 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017546 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017547 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017548
17549 status = wlan_hdd_get_station_stats(adapter);
17550 if (!VOS_IS_STATUS_SUCCESS(status)) {
17551 hddLog(VOS_TRACE_LEVEL_ERROR,
17552 "Failed to get SAP stats; status:%d", status);
17553 return 0;
17554 }
17555
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017556 peerMacAddr = (v_MACADDR_t *)mac;
17557 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17558 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17559 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17560
17561 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17562 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017563 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017564 }
17565
Dustin Brown8c1d4092017-07-28 18:08:01 +053017566 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17567
17568 return 0;
17569}
17570
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017571static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17573 const u8* mac,
17574#else
17575 u8* mac,
17576#endif
17577 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017578{
17579 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17580 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17581 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017582 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017583
17584 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17585 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017586
17587 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17588 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17589 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17590 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17591 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17592 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17593 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017594 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017595 tANI_U16 myRate;
17596 tANI_U16 currentRate = 0;
17597 tANI_U8 maxSpeedMCS = 0;
17598 tANI_U8 maxMCSIdx = 0;
17599 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017600 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017601 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017602 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017603
Leo Chang6f8870f2013-03-26 18:11:36 -070017604#ifdef WLAN_FEATURE_11AC
17605 tANI_U32 vht_mcs_map;
17606 eDataRate11ACMaxMcs vhtMaxMcs;
17607#endif /* WLAN_FEATURE_11AC */
17608
Jeff Johnsone7245742012-09-05 17:12:55 -070017609 ENTER();
17610
Dustin Brown8c1d4092017-07-28 18:08:01 +053017611 status = wlan_hdd_validate_context(pHddCtx);
17612 if (0 != status)
17613 {
17614 return status;
17615 }
17616
17617 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017618 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017619
Jeff Johnson295189b2012-06-20 16:38:30 -070017620 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17621 (0 == ssidlen))
17622 {
17623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17624 " Invalid ssidlen, %d", __func__, ssidlen);
17625 /*To keep GUI happy*/
17626 return 0;
17627 }
17628
Mukul Sharma811205f2014-07-09 21:07:30 +053017629 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17630 {
17631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17632 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017633 /* return a cached value */
17634 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017635 return 0;
17636 }
17637
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017638 wlan_hdd_get_station_stats(pAdapter);
17639 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017640
Kiet Lam3b17fc82013-09-27 05:24:08 +053017641 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017642 wlan_hdd_get_snr(pAdapter, &snr);
17643 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017644 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017645 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017646 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017647 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017648
c_hpothu09f19542014-05-30 21:53:31 +053017649 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017650 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17651 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017652 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017653 {
17654 rate_flags = pAdapter->maxRateFlags;
17655 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017656
Jeff Johnson295189b2012-06-20 16:38:30 -070017657 //convert to the UI units of 100kbps
17658 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17659
17660#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017661 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 -070017662 sinfo->signal,
17663 pCfg->reportMaxLinkSpeed,
17664 myRate,
17665 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017666 (int) pCfg->linkSpeedRssiMid,
17667 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017668 (int) rate_flags,
17669 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017670#endif //LINKSPEED_DEBUG_ENABLED
17671
17672 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17673 {
17674 // we do not want to necessarily report the current speed
17675 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17676 {
17677 // report the max possible speed
17678 rssidx = 0;
17679 }
17680 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17681 {
17682 // report the max possible speed with RSSI scaling
17683 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17684 {
17685 // report the max possible speed
17686 rssidx = 0;
17687 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017688 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017689 {
17690 // report middle speed
17691 rssidx = 1;
17692 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017693 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17694 {
17695 // report middle speed
17696 rssidx = 2;
17697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017698 else
17699 {
17700 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017701 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017702 }
17703 }
17704 else
17705 {
17706 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17707 hddLog(VOS_TRACE_LEVEL_ERROR,
17708 "%s: Invalid value for reportMaxLinkSpeed: %u",
17709 __func__, pCfg->reportMaxLinkSpeed);
17710 rssidx = 0;
17711 }
17712
17713 maxRate = 0;
17714
17715 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017716 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17717 OperationalRates, &ORLeng))
17718 {
17719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17720 /*To keep GUI happy*/
17721 return 0;
17722 }
17723
Jeff Johnson295189b2012-06-20 16:38:30 -070017724 for (i = 0; i < ORLeng; i++)
17725 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017726 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017727 {
17728 /* Validate Rate Set */
17729 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17730 {
17731 currentRate = supported_data_rate[j].supported_rate[rssidx];
17732 break;
17733 }
17734 }
17735 /* Update MAX rate */
17736 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17737 }
17738
17739 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017740 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17741 ExtendedRates, &ERLeng))
17742 {
17743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17744 /*To keep GUI happy*/
17745 return 0;
17746 }
17747
Jeff Johnson295189b2012-06-20 16:38:30 -070017748 for (i = 0; i < ERLeng; i++)
17749 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017750 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017751 {
17752 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17753 {
17754 currentRate = supported_data_rate[j].supported_rate[rssidx];
17755 break;
17756 }
17757 }
17758 /* Update MAX rate */
17759 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17760 }
c_hpothu79aab322014-07-14 21:11:01 +053017761
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017762 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017763 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017764 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017765 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017766 {
c_hpothu79aab322014-07-14 21:11:01 +053017767 if (rate_flags & eHAL_TX_RATE_VHT80)
17768 mode = 2;
17769 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17770 mode = 1;
17771 else
17772 mode = 0;
17773
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017774 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17775 MCSRates, &MCSLeng))
17776 {
17777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17778 /*To keep GUI happy*/
17779 return 0;
17780 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017781 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017782#ifdef WLAN_FEATURE_11AC
17783 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017784 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017785 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017786 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017787 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017788 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017789 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017790 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017791 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017792 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017793 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017794 maxMCSIdx = 7;
17795 }
17796 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17797 {
17798 maxMCSIdx = 8;
17799 }
17800 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17801 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017802 //VHT20 is supporting 0~8
17803 if (rate_flags & eHAL_TX_RATE_VHT20)
17804 maxMCSIdx = 8;
17805 else
17806 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017807 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017808
c_hpothu79aab322014-07-14 21:11:01 +053017809 if (0 != rssidx)/*check for scaled */
17810 {
17811 //get middle rate MCS index if rssi=1/2
17812 for (i=0; i <= maxMCSIdx; i++)
17813 {
17814 if (sinfo->signal <= rssiMcsTbl[mode][i])
17815 {
17816 maxMCSIdx = i;
17817 break;
17818 }
17819 }
17820 }
17821
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017822 if (rate_flags & eHAL_TX_RATE_VHT80)
17823 {
17824 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17825 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17826 }
17827 else if (rate_flags & eHAL_TX_RATE_VHT40)
17828 {
17829 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17830 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17831 }
17832 else if (rate_flags & eHAL_TX_RATE_VHT20)
17833 {
17834 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17835 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17836 }
17837
Leo Chang6f8870f2013-03-26 18:11:36 -070017838 maxSpeedMCS = 1;
17839 if (currentRate > maxRate)
17840 {
17841 maxRate = currentRate;
17842 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017843
Leo Chang6f8870f2013-03-26 18:11:36 -070017844 }
17845 else
17846#endif /* WLAN_FEATURE_11AC */
17847 {
17848 if (rate_flags & eHAL_TX_RATE_HT40)
17849 {
17850 rateFlag |= 1;
17851 }
17852 if (rate_flags & eHAL_TX_RATE_SGI)
17853 {
17854 rateFlag |= 2;
17855 }
17856
Girish Gowli01abcee2014-07-31 20:18:55 +053017857 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017858 if (rssidx == 1 || rssidx == 2)
17859 {
17860 //get middle rate MCS index if rssi=1/2
17861 for (i=0; i <= 7; i++)
17862 {
17863 if (sinfo->signal <= rssiMcsTbl[mode][i])
17864 {
17865 temp = i+1;
17866 break;
17867 }
17868 }
17869 }
c_hpothu79aab322014-07-14 21:11:01 +053017870
17871 for (i = 0; i < MCSLeng; i++)
17872 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017873 for (j = 0; j < temp; j++)
17874 {
17875 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17876 {
17877 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017878 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017879 break;
17880 }
17881 }
17882 if ((j < temp) && (currentRate > maxRate))
17883 {
17884 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017886 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017887 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017888 }
17889 }
17890
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017891 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17892 {
17893 maxRate = myRate;
17894 maxSpeedMCS = 1;
17895 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17896 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017897 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017898 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017899 {
17900 maxRate = myRate;
17901 if (rate_flags & eHAL_TX_RATE_LEGACY)
17902 {
17903 maxSpeedMCS = 0;
17904 }
17905 else
17906 {
17907 maxSpeedMCS = 1;
17908 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17909 }
17910 }
17911
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017912 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017913 {
17914 sinfo->txrate.legacy = maxRate;
17915#ifdef LINKSPEED_DEBUG_ENABLED
17916 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17917#endif //LINKSPEED_DEBUG_ENABLED
17918 }
17919 else
17920 {
17921 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017922#ifdef WLAN_FEATURE_11AC
17923 sinfo->txrate.nss = 1;
17924 if (rate_flags & eHAL_TX_RATE_VHT80)
17925 {
17926 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17928 defined(WITH_BACKPORTS)
17929 sinfo->txrate.bw = RATE_INFO_BW_80;
17930#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017931 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017932#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070017933 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017934 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017935 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017936 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17938 defined(WITH_BACKPORTS)
17939 sinfo->txrate.bw = RATE_INFO_BW_40;
17940#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017941 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017942#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017943 }
17944 else if (rate_flags & eHAL_TX_RATE_VHT20)
17945 {
17946 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17947 }
17948#endif /* WLAN_FEATURE_11AC */
17949 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17950 {
17951 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17952 if (rate_flags & eHAL_TX_RATE_HT40)
17953 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
17955 defined(WITH_BACKPORTS)
17956 sinfo->txrate.bw = RATE_INFO_BW_40;
17957#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017958 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017959#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017960 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017961 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017962 if (rate_flags & eHAL_TX_RATE_SGI)
17963 {
17964 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17965 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017966
Jeff Johnson295189b2012-06-20 16:38:30 -070017967#ifdef LINKSPEED_DEBUG_ENABLED
17968 pr_info("Reporting MCS rate %d flags %x\n",
17969 sinfo->txrate.mcs,
17970 sinfo->txrate.flags );
17971#endif //LINKSPEED_DEBUG_ENABLED
17972 }
17973 }
17974 else
17975 {
17976 // report current rate instead of max rate
17977
17978 if (rate_flags & eHAL_TX_RATE_LEGACY)
17979 {
17980 //provide to the UI in units of 100kbps
17981 sinfo->txrate.legacy = myRate;
17982#ifdef LINKSPEED_DEBUG_ENABLED
17983 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17984#endif //LINKSPEED_DEBUG_ENABLED
17985 }
17986 else
17987 {
17988 //must be MCS
17989 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017990#ifdef WLAN_FEATURE_11AC
17991 sinfo->txrate.nss = 1;
17992 if (rate_flags & eHAL_TX_RATE_VHT80)
17993 {
17994 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17995 }
17996 else
17997#endif /* WLAN_FEATURE_11AC */
17998 {
17999 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18000 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018001 if (rate_flags & eHAL_TX_RATE_SGI)
18002 {
18003 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18004 }
18005 if (rate_flags & eHAL_TX_RATE_HT40)
18006 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18008 defined(WITH_BACKPORTS)
18009 sinfo->txrate.bw = RATE_INFO_BW_40;
18010#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018011 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018012#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018013 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018014#ifdef WLAN_FEATURE_11AC
18015 else if (rate_flags & eHAL_TX_RATE_VHT80)
18016 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18018 defined(WITH_BACKPORTS)
18019 sinfo->txrate.bw = RATE_INFO_BW_80;
18020#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018021 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018022#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018023 }
18024#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018025#ifdef LINKSPEED_DEBUG_ENABLED
18026 pr_info("Reporting actual MCS rate %d flags %x\n",
18027 sinfo->txrate.mcs,
18028 sinfo->txrate.flags );
18029#endif //LINKSPEED_DEBUG_ENABLED
18030 }
18031 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018032
18033#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18034 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018035 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018036#else
18037 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18038#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018039
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018040 sinfo->tx_packets =
18041 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18042 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18043 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18044 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18045
18046 sinfo->tx_retries =
18047 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18048 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18049 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18050 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18051
18052 sinfo->tx_failed =
18053 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18054 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18055 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18056 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18057
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018058#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18059 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018060 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018061 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018062 STATION_INFO_TX_PACKETS |
18063 STATION_INFO_TX_RETRIES |
18064 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018065#else
18066 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18067 BIT(NL80211_STA_INFO_TX_PACKETS) |
18068 BIT(NL80211_STA_INFO_TX_RETRIES) |
18069 BIT(NL80211_STA_INFO_TX_FAILED);
18070#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018071
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018072 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018073
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018074 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18075 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018076 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18077 &sinfo->txrate, sizeof(sinfo->txrate));
18078
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018079 if (rate_flags & eHAL_TX_RATE_LEGACY)
18080 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18081 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18082 sinfo->rx_packets);
18083 else
18084 hddLog(LOG1,
18085 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18086 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18087 sinfo->tx_packets, sinfo->rx_packets);
18088
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018089 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18090 TRACE_CODE_HDD_CFG80211_GET_STA,
18091 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018092 EXIT();
18093 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018094}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18096static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18097 const u8* mac, struct station_info *sinfo)
18098#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018099static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18100 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018101#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018102{
18103 int ret;
18104
18105 vos_ssr_protect(__func__);
18106 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18107 vos_ssr_unprotect(__func__);
18108
18109 return ret;
18110}
18111
18112static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018113 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018114{
18115 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018116 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018117 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018118 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018119
Jeff Johnsone7245742012-09-05 17:12:55 -070018120 ENTER();
18121
Jeff Johnson295189b2012-06-20 16:38:30 -070018122 if (NULL == pAdapter)
18123 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018125 return -ENODEV;
18126 }
18127
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018128 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18129 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18130 pAdapter->sessionId, timeout));
18131
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018132 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018133 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018134 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018135 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018136 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018137 }
18138
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018139 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18140 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18141 (pHddCtx->cfg_ini->fhostArpOffload) &&
18142 (eConnectionState_Associated ==
18143 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18144 {
Amar Singhald53568e2013-09-26 11:03:45 -070018145
18146 hddLog(VOS_TRACE_LEVEL_INFO,
18147 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018148 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018149 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18150 {
18151 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018152 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018153 __func__, vos_status);
18154 }
18155 }
18156
Jeff Johnson295189b2012-06-20 16:38:30 -070018157 /**The get power cmd from the supplicant gets updated by the nl only
18158 *on successful execution of the function call
18159 *we are oppositely mapped w.r.t mode in the driver
18160 **/
18161 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18162
18163 if (VOS_STATUS_E_FAILURE == vos_status)
18164 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18166 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018167 return -EINVAL;
18168 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018169 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018170 return 0;
18171}
18172
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018173static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18174 struct net_device *dev, bool mode, int timeout)
18175{
18176 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018177
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018178 vos_ssr_protect(__func__);
18179 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18180 vos_ssr_unprotect(__func__);
18181
18182 return ret;
18183}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018184
Jeff Johnson295189b2012-06-20 16:38:30 -070018185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018186static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18187 struct net_device *netdev,
18188 u8 key_index)
18189{
18190 ENTER();
18191 return 0;
18192}
18193
Jeff Johnson295189b2012-06-20 16:38:30 -070018194static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018195 struct net_device *netdev,
18196 u8 key_index)
18197{
18198 int ret;
18199 vos_ssr_protect(__func__);
18200 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18201 vos_ssr_unprotect(__func__);
18202 return ret;
18203}
18204#endif //LINUX_VERSION_CODE
18205
18206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18207static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18208 struct net_device *dev,
18209 struct ieee80211_txq_params *params)
18210{
18211 ENTER();
18212 return 0;
18213}
18214#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18215static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18216 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018217{
Jeff Johnsone7245742012-09-05 17:12:55 -070018218 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018219 return 0;
18220}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018221#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018222
18223#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18224static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018225 struct net_device *dev,
18226 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018227{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018228 int ret;
18229
18230 vos_ssr_protect(__func__);
18231 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18232 vos_ssr_unprotect(__func__);
18233 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018234}
18235#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18236static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18237 struct ieee80211_txq_params *params)
18238{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018239 int ret;
18240
18241 vos_ssr_protect(__func__);
18242 ret = __wlan_hdd_set_txq_params(wiphy, params);
18243 vos_ssr_unprotect(__func__);
18244 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018245}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018246#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018247
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018248static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018249 struct net_device *dev,
18250 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018251{
18252 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018253 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018254 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018255 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018256 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018257 v_CONTEXT_t pVosContext = NULL;
18258 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018259
Jeff Johnsone7245742012-09-05 17:12:55 -070018260 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018261
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018262 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018263 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018265 return -EINVAL;
18266 }
18267
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018268 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18269 TRACE_CODE_HDD_CFG80211_DEL_STA,
18270 pAdapter->sessionId, pAdapter->device_mode));
18271
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018272 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18273 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018274 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018275 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018276 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018277 }
18278
Jeff Johnson295189b2012-06-20 16:38:30 -070018279 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018280 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018281 )
18282 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018283 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18284 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18285 if(pSapCtx == NULL){
18286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18287 FL("psapCtx is NULL"));
18288 return -ENOENT;
18289 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018290 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18291 {
18292 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18293 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18294 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18295 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018296 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018297 {
18298 v_U16_t i;
18299 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18300 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018301 if ((pSapCtx->aStaInfo[i].isUsed) &&
18302 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018303 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018304 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018305 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018306 ETHER_ADDR_LEN);
18307
Jeff Johnson295189b2012-06-20 16:38:30 -070018308 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018309 "%s: Delete STA with MAC::"
18310 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018311 __func__,
18312 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18313 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018314 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018315 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018316 }
18317 }
18318 }
18319 else
18320 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018321
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018322 vos_status = hdd_softap_GetStaId(pAdapter,
18323 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018324 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18325 {
18326 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018327 "%s: Skip this DEL STA as this is not used::"
18328 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018329 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018330 return -ENOENT;
18331 }
18332
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018333 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018334 {
18335 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018336 "%s: Skip this DEL STA as deauth is in progress::"
18337 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018338 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018339 return -ENOENT;
18340 }
18341
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018342 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018343
Jeff Johnson295189b2012-06-20 16:38:30 -070018344 hddLog(VOS_TRACE_LEVEL_INFO,
18345 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018346 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018347 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018348 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018349
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018350 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018351 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18352 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018353 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018354 hddLog(VOS_TRACE_LEVEL_INFO,
18355 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018356 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018357 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018358 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018359 return -ENOENT;
18360 }
18361
Jeff Johnson295189b2012-06-20 16:38:30 -070018362 }
18363 }
18364
18365 EXIT();
18366
18367 return 0;
18368}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018369
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018370#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018371int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018372 struct net_device *dev,
18373 struct station_del_parameters *param)
18374#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018375#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018376int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018377 struct net_device *dev, const u8 *mac)
18378#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018379int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018380 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018381#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018382#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018383{
18384 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018385 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018386
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018387 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018388
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018389#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018390 if (NULL == param) {
18391 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018392 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018393 return -EINVAL;
18394 }
18395
18396 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18397 param->subtype, &delStaParams);
18398
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018399#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018400 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018401 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018402#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018403 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18404
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018405 vos_ssr_unprotect(__func__);
18406
18407 return ret;
18408}
18409
18410static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018411 struct net_device *dev,
18412#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18413 const u8 *mac,
18414#else
18415 u8 *mac,
18416#endif
18417 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018418{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018419 hdd_adapter_t *pAdapter;
18420 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018421 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018422#ifdef FEATURE_WLAN_TDLS
18423 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018424
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018425 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018426
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018427 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18428 if (NULL == pAdapter)
18429 {
18430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18431 "%s: Adapter is NULL",__func__);
18432 return -EINVAL;
18433 }
18434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18435 status = wlan_hdd_validate_context(pHddCtx);
18436 if (0 != status)
18437 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018438 return status;
18439 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018440
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018441 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18442 TRACE_CODE_HDD_CFG80211_ADD_STA,
18443 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018444 mask = params->sta_flags_mask;
18445
18446 set = params->sta_flags_set;
18447
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018449 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18450 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018451
18452 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18453 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018454 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018455 }
18456 }
18457#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018458 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018459 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018460}
18461
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18463static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18464 struct net_device *dev, const u8 *mac,
18465 struct station_parameters *params)
18466#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018467static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18468 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018469#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018470{
18471 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018472
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018473 vos_ssr_protect(__func__);
18474 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18475 vos_ssr_unprotect(__func__);
18476
18477 return ret;
18478}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018479#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018480
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018481static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018482 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018483{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018484 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18485 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018486 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018487 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018488 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018489 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018490
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018491 ENTER();
18492
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018493 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018494 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018495 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018497 return -EINVAL;
18498 }
18499
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018500 if (!pmksa) {
18501 hddLog(LOGE, FL("pmksa is NULL"));
18502 return -EINVAL;
18503 }
18504
18505 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018506 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018507 pmksa->bssid, pmksa->pmkid);
18508 return -EINVAL;
18509 }
18510
18511 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18512 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18513
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018514 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18515 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018516 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018517 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018518 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018519 }
18520
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018521 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018522 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18523
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018524 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18525 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018526
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018527 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018528 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018529 &pmk_id, 1, FALSE);
18530
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018531 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18532 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18533 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018534
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018535 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018536 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018537}
18538
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018539static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18540 struct cfg80211_pmksa *pmksa)
18541{
18542 int ret;
18543
18544 vos_ssr_protect(__func__);
18545 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18546 vos_ssr_unprotect(__func__);
18547
18548 return ret;
18549}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018550
Wilson Yang6507c4e2013-10-01 20:11:19 -070018551
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018552static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018553 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018554{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018555 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18556 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018557 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018558 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018560 ENTER();
18561
Wilson Yang6507c4e2013-10-01 20:11:19 -070018562 /* Validate pAdapter */
18563 if (NULL == pAdapter)
18564 {
18565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18566 return -EINVAL;
18567 }
18568
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018569 if (!pmksa) {
18570 hddLog(LOGE, FL("pmksa is NULL"));
18571 return -EINVAL;
18572 }
18573
18574 if (!pmksa->bssid) {
18575 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18576 return -EINVAL;
18577 }
18578
Kiet Lam98c46a12014-10-31 15:34:57 -070018579 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18580 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18581
Wilson Yang6507c4e2013-10-01 20:11:19 -070018582 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18583 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018584 if (0 != status)
18585 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018586 return status;
18587 }
18588
18589 /*Retrieve halHandle*/
18590 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18591
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018592 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18593 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18594 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018595 /* Delete the PMKID CSR cache */
18596 if (eHAL_STATUS_SUCCESS !=
18597 sme_RoamDelPMKIDfromCache(halHandle,
18598 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18599 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18600 MAC_ADDR_ARRAY(pmksa->bssid));
18601 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018602 }
18603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018604 EXIT();
18605 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018606}
18607
Wilson Yang6507c4e2013-10-01 20:11:19 -070018608
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018609static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18610 struct cfg80211_pmksa *pmksa)
18611{
18612 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018613
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018614 vos_ssr_protect(__func__);
18615 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18616 vos_ssr_unprotect(__func__);
18617
18618 return ret;
18619
18620}
18621
18622static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018623{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18625 tHalHandle halHandle;
18626 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018627 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018628
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018629 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018630
18631 /* Validate pAdapter */
18632 if (NULL == pAdapter)
18633 {
18634 hddLog(VOS_TRACE_LEVEL_ERROR,
18635 "%s: Invalid Adapter" ,__func__);
18636 return -EINVAL;
18637 }
18638
18639 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18640 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018641 if (0 != status)
18642 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018643 return status;
18644 }
18645
18646 /*Retrieve halHandle*/
18647 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18648
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018649 /* Flush the PMKID cache in CSR */
18650 if (eHAL_STATUS_SUCCESS !=
18651 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18653 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018654 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018655 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018656 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018657}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018658
18659static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18660{
18661 int ret;
18662
18663 vos_ssr_protect(__func__);
18664 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18665 vos_ssr_unprotect(__func__);
18666
18667 return ret;
18668}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018669#endif
18670
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018671#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018672static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18673 struct net_device *dev,
18674 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018675{
18676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18677 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018678 hdd_context_t *pHddCtx;
18679 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018680
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018681 ENTER();
18682
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018683 if (NULL == pAdapter)
18684 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018686 return -ENODEV;
18687 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018688 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18689 ret = wlan_hdd_validate_context(pHddCtx);
18690 if (0 != ret)
18691 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018692 return ret;
18693 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018694 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018695 if (NULL == pHddStaCtx)
18696 {
18697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18698 return -EINVAL;
18699 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018700
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018701 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18702 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18703 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018704 // Added for debug on reception of Re-assoc Req.
18705 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18706 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018707 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018708 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018709 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018710 }
18711
18712#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018713 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018714 ftie->ie_len);
18715#endif
18716
18717 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018718 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18719 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018720 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018721
18722 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018723 return 0;
18724}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018725
18726static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18727 struct net_device *dev,
18728 struct cfg80211_update_ft_ies_params *ftie)
18729{
18730 int ret;
18731
18732 vos_ssr_protect(__func__);
18733 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18734 vos_ssr_unprotect(__func__);
18735
18736 return ret;
18737}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018738#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018739
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018740#ifdef FEATURE_WLAN_SCAN_PNO
18741
18742void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18743 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18744{
18745 int ret;
18746 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18747 hdd_context_t *pHddCtx;
18748
Nirav Shah80830bf2013-12-31 16:35:12 +053018749 ENTER();
18750
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018751 if (NULL == pAdapter)
18752 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018754 "%s: HDD adapter is Null", __func__);
18755 return ;
18756 }
18757
18758 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18759 if (NULL == pHddCtx)
18760 {
18761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18762 "%s: HDD context is Null!!!", __func__);
18763 return ;
18764 }
18765
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018766 spin_lock(&pHddCtx->schedScan_lock);
18767 if (TRUE == pHddCtx->isWiphySuspended)
18768 {
18769 pHddCtx->isSchedScanUpdatePending = TRUE;
18770 spin_unlock(&pHddCtx->schedScan_lock);
18771 hddLog(VOS_TRACE_LEVEL_INFO,
18772 "%s: Update cfg80211 scan database after it resume", __func__);
18773 return ;
18774 }
18775 spin_unlock(&pHddCtx->schedScan_lock);
18776
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018777 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18778
18779 if (0 > ret)
18780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018781 else
18782 {
18783 /* Acquire wakelock to handle the case where APP's tries to suspend
18784 * immediatly after the driver gets connect request(i.e after pno)
18785 * from supplicant, this result in app's is suspending and not able
18786 * to process the connect request to AP */
18787 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18788 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018789 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18791 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018792}
18793
18794/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018795 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018796 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018797 */
18798static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18799{
18800 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18801 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018802 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018803 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18804 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018805
18806 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18807 {
18808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18809 "%s: PNO is allowed only in STA interface", __func__);
18810 return eHAL_STATUS_FAILURE;
18811 }
18812
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018813 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18814
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018815 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018816 * active sessions. PNO is allowed only in case when sap session
18817 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018818 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018819 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18820 {
18821 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018822 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018823
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018824 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18825 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18826 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18827 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018828 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18829 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018830 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018831 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018832 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018833 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018834 }
18835 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18836 pAdapterNode = pNext;
18837 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018838 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018839}
18840
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018841void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18842{
18843 hdd_adapter_t *pAdapter = callbackContext;
18844 hdd_context_t *pHddCtx;
18845
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018846 ENTER();
18847
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018848 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18849 {
18850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18851 FL("Invalid adapter or adapter has invalid magic"));
18852 return;
18853 }
18854
18855 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18856 if (0 != wlan_hdd_validate_context(pHddCtx))
18857 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018858 return;
18859 }
18860
c_hpothub53c45d2014-08-18 16:53:14 +053018861 if (VOS_STATUS_SUCCESS != status)
18862 {
18863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018864 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018865 pHddCtx->isPnoEnable = FALSE;
18866 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018867
18868 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18869 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018870 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018871}
18872
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018873#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18874 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18875/**
18876 * hdd_config_sched_scan_plan() - configures the sched scan plans
18877 * from the framework.
18878 * @pno_req: pointer to PNO scan request
18879 * @request: pointer to scan request from framework
18880 *
18881 * Return: None
18882 */
18883static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18884 struct cfg80211_sched_scan_request *request,
18885 hdd_context_t *hdd_ctx)
18886{
18887 v_U32_t i = 0;
18888
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018889 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018890 for (i = 0; i < request->n_scan_plans; i++)
18891 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018892 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18893 request->scan_plans[i].iterations;
18894 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18895 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018896 }
18897}
18898#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018899static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018900 struct cfg80211_sched_scan_request *request,
18901 hdd_context_t *hdd_ctx)
18902{
18903 v_U32_t i, temp_int;
18904 /* Driver gets only one time interval which is hardcoded in
18905 * supplicant for 10000ms. Taking power consumption into account 6
18906 * timers will be used, Timervalue is increased exponentially
18907 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18908 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18909 * If it is set to 0 only one timer will be used and PNO scan cycle
18910 * will be repeated after each interval specified by supplicant
18911 * till PNO is disabled.
18912 */
18913 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018914 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018915 HDD_PNO_SCAN_TIMERS_SET_ONE;
18916 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018917 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018918 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18919
18920 temp_int = (request->interval)/1000;
18921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18922 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18923 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018924 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018925 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018926 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018927 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018928 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018929 temp_int *= 2;
18930 }
18931 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018932 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018933}
18934#endif
18935
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018936/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018937 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18938 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018939 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018940static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018941 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18942{
18943 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018944 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018945 hdd_context_t *pHddCtx;
18946 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018947 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018948 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18949 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018950 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18951 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018952 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018953 hdd_config_t *pConfig = NULL;
18954 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018956 ENTER();
18957
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018958 if (NULL == pAdapter)
18959 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018961 "%s: HDD adapter is Null", __func__);
18962 return -ENODEV;
18963 }
18964
18965 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018966 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018967
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018968 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018969 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018970 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018971 }
18972
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018973 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018974 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18975 if (NULL == hHal)
18976 {
18977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18978 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018979 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018980 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018981 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18982 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18983 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018984 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018985 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018986 {
18987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18988 "%s: aborting the existing scan is unsuccessfull", __func__);
18989 return -EBUSY;
18990 }
18991
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018992 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018993 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018995 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018996 return -EBUSY;
18997 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018998
c_hpothu37f21312014-04-09 21:49:54 +053018999 if (TRUE == pHddCtx->isPnoEnable)
19000 {
19001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19002 FL("already PNO is enabled"));
19003 return -EBUSY;
19004 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019005
19006 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19007 {
19008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19009 "%s: abort ROC failed ", __func__);
19010 return -EBUSY;
19011 }
19012
c_hpothu37f21312014-04-09 21:49:54 +053019013 pHddCtx->isPnoEnable = TRUE;
19014
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019015 pnoRequest.enable = 1; /*Enable PNO */
19016 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019017
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019018 if (( !pnoRequest.ucNetworksCount ) ||
19019 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019020 {
19021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019022 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019023 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019024 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019025 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019026 goto error;
19027 }
19028
19029 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19030 {
19031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019032 "%s: Incorrect number of channels %d",
19033 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019034 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019035 goto error;
19036 }
19037
19038 /* Framework provides one set of channels(all)
19039 * common for all saved profile */
19040 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19041 channels_allowed, &num_channels_allowed))
19042 {
19043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19044 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019045 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019046 goto error;
19047 }
19048 /* Checking each channel against allowed channel list */
19049 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019050 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019051 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019052 char chList [(request->n_channels*5)+1];
19053 int len;
19054 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019055 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019056 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019057 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019058 if (request->channels[i]->hw_value == channels_allowed[indx])
19059 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019060 if ((!pConfig->enableDFSPnoChnlScan) &&
19061 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19062 {
19063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19064 "%s : Dropping DFS channel : %d",
19065 __func__,channels_allowed[indx]);
19066 num_ignore_dfs_ch++;
19067 break;
19068 }
19069
Nirav Shah80830bf2013-12-31 16:35:12 +053019070 valid_ch[num_ch++] = request->channels[i]->hw_value;
19071 len += snprintf(chList+len, 5, "%d ",
19072 request->channels[i]->hw_value);
19073 break ;
19074 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019075 }
19076 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019077 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019078
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019079 /*If all channels are DFS and dropped, then ignore the PNO request*/
19080 if (num_ignore_dfs_ch == request->n_channels)
19081 {
19082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19083 "%s : All requested channels are DFS channels", __func__);
19084 ret = -EINVAL;
19085 goto error;
19086 }
19087 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019088
19089 pnoRequest.aNetworks =
19090 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19091 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019092 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019093 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19094 FL("failed to allocate memory aNetworks %u"),
19095 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19096 goto error;
19097 }
19098 vos_mem_zero(pnoRequest.aNetworks,
19099 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19100
19101 /* Filling per profile params */
19102 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19103 {
19104 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019105 request->match_sets[i].ssid.ssid_len;
19106
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019107 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19108 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019109 {
19110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019111 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019112 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019113 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019114 goto error;
19115 }
19116
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019117 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019118 request->match_sets[i].ssid.ssid,
19119 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19121 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019122 i, pnoRequest.aNetworks[i].ssId.ssId);
19123 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19124 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19125 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019126
19127 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019128 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19129 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019130
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019131 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019132 }
19133
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019134 for (i = 0; i < request->n_ssids; i++)
19135 {
19136 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019137 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019138 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019139 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019140 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019141 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019142 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019143 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019144 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019145 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019146 break;
19147 }
19148 j++;
19149 }
19150 }
19151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19152 "Number of hidden networks being Configured = %d",
19153 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019155 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019156
19157 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19158 if (pnoRequest.p24GProbeTemplate == NULL)
19159 {
19160 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19161 FL("failed to allocate memory p24GProbeTemplate %u"),
19162 SIR_PNO_MAX_PB_REQ_SIZE);
19163 goto error;
19164 }
19165
19166 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19167 if (pnoRequest.p5GProbeTemplate == NULL)
19168 {
19169 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19170 FL("failed to allocate memory p5GProbeTemplate %u"),
19171 SIR_PNO_MAX_PB_REQ_SIZE);
19172 goto error;
19173 }
19174
19175 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19176 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19177
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019178 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19179 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019180 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019181 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19182 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19183 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019184
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019185 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19186 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19187 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019188 }
19189
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019190 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019191
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019192 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019193
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019194 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019195 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19196 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019197 pAdapter->pno_req_status = 0;
19198
Nirav Shah80830bf2013-12-31 16:35:12 +053019199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19200 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019201 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19202 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019203
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019204 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019205 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019206 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19207 if (eHAL_STATUS_SUCCESS != status)
19208 {
19209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019210 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019211 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019212 goto error;
19213 }
19214
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019215 ret = wait_for_completion_timeout(
19216 &pAdapter->pno_comp_var,
19217 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19218 if (0 >= ret)
19219 {
19220 // Did not receive the response for PNO enable in time.
19221 // Assuming the PNO enable was success.
19222 // Returning error from here, because we timeout, results
19223 // in side effect of Wifi (Wifi Setting) not to work.
19224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19225 FL("Timed out waiting for PNO to be Enabled"));
19226 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019227 }
19228
19229 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019230 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019231
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019232error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19234 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019235 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019236 if (pnoRequest.aNetworks)
19237 vos_mem_free(pnoRequest.aNetworks);
19238 if (pnoRequest.p24GProbeTemplate)
19239 vos_mem_free(pnoRequest.p24GProbeTemplate);
19240 if (pnoRequest.p5GProbeTemplate)
19241 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019242
19243 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019244 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019245}
19246
19247/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019248 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19249 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019250 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019251static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19252 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19253{
19254 int ret;
19255
19256 vos_ssr_protect(__func__);
19257 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19258 vos_ssr_unprotect(__func__);
19259
19260 return ret;
19261}
19262
19263/*
19264 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19265 * Function to disable PNO
19266 */
19267static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019268 struct net_device *dev)
19269{
19270 eHalStatus status = eHAL_STATUS_FAILURE;
19271 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19272 hdd_context_t *pHddCtx;
19273 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019274 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019275 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019276
19277 ENTER();
19278
19279 if (NULL == pAdapter)
19280 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019282 "%s: HDD adapter is Null", __func__);
19283 return -ENODEV;
19284 }
19285
19286 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019287
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019288 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019289 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019291 "%s: HDD context is Null", __func__);
19292 return -ENODEV;
19293 }
19294
19295 /* The return 0 is intentional when isLogpInProgress and
19296 * isLoadUnloadInProgress. We did observe a crash due to a return of
19297 * failure in sched_scan_stop , especially for a case where the unload
19298 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19299 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19300 * success. If it returns a failure , then its next invocation due to the
19301 * clean up of the second interface will have the dev pointer corresponding
19302 * to the first one leading to a crash.
19303 */
19304 if (pHddCtx->isLogpInProgress)
19305 {
19306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19307 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019308 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019309 return ret;
19310 }
19311
Mihir Shete18156292014-03-11 15:38:30 +053019312 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019313 {
19314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19315 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19316 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019317 }
19318
19319 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19320 if (NULL == hHal)
19321 {
19322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19323 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019324 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019325 }
19326
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019327 pnoRequest.enable = 0; /* Disable PNO */
19328 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019329
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019330 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19331 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19332 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019333
19334 INIT_COMPLETION(pAdapter->pno_comp_var);
19335 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19336 pnoRequest.callbackContext = pAdapter;
19337 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019338 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019339 pAdapter->sessionId,
19340 NULL, pAdapter);
19341 if (eHAL_STATUS_SUCCESS != status)
19342 {
19343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19344 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019345 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019346 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019347 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019348 ret = wait_for_completion_timeout(
19349 &pAdapter->pno_comp_var,
19350 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19351 if (0 >= ret)
19352 {
19353 // Did not receive the response for PNO disable in time.
19354 // Assuming the PNO disable was success.
19355 // Returning error from here, because we timeout, results
19356 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019358 FL("Timed out waiting for PNO to be disabled"));
19359 ret = 0;
19360 }
19361
19362 ret = pAdapter->pno_req_status;
19363 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019364
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019365error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019367 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019368
19369 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019370 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019371}
19372
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019373/*
19374 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19375 * NL interface to disable PNO
19376 */
19377static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19378 struct net_device *dev)
19379{
19380 int ret;
19381
19382 vos_ssr_protect(__func__);
19383 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19384 vos_ssr_unprotect(__func__);
19385
19386 return ret;
19387}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019388#endif /*FEATURE_WLAN_SCAN_PNO*/
19389
19390
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019391#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019392#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019393static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19394 struct net_device *dev,
19395 u8 *peer, u8 action_code,
19396 u8 dialog_token,
19397 u16 status_code, u32 peer_capability,
19398 const u8 *buf, size_t len)
19399#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19401 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019402static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19403 struct net_device *dev,
19404 const u8 *peer, u8 action_code,
19405 u8 dialog_token, u16 status_code,
19406 u32 peer_capability, bool initiator,
19407 const u8 *buf, size_t len)
19408#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19409static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19410 struct net_device *dev,
19411 const u8 *peer, u8 action_code,
19412 u8 dialog_token, u16 status_code,
19413 u32 peer_capability, const u8 *buf,
19414 size_t len)
19415#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19416static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19417 struct net_device *dev,
19418 u8 *peer, u8 action_code,
19419 u8 dialog_token,
19420 u16 status_code, u32 peer_capability,
19421 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019422#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019423static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19424 struct net_device *dev,
19425 u8 *peer, u8 action_code,
19426 u8 dialog_token,
19427 u16 status_code, const u8 *buf,
19428 size_t len)
19429#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019430#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019431{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019432 hdd_adapter_t *pAdapter;
19433 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019434 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019435 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019436 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019437 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019438 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019439 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019440#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019441 u32 peer_capability = 0;
19442#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019443 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019444 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019445 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019446
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019447 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19448 if (NULL == pAdapter)
19449 {
19450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19451 "%s: Adapter is NULL",__func__);
19452 return -EINVAL;
19453 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019454 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19455 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19456 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019457
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019458 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019459 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019462 "Invalid arguments");
19463 return -EINVAL;
19464 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019465
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019466 if (pHddCtx->isLogpInProgress)
19467 {
19468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19469 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019470 wlan_hdd_tdls_set_link_status(pAdapter,
19471 peer,
19472 eTDLS_LINK_IDLE,
19473 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019474 return -EBUSY;
19475 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019476
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019477 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19478 {
19479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19480 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19481 return -EAGAIN;
19482 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019483
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019484 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19485 if (!pHddTdlsCtx) {
19486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19487 "%s: pHddTdlsCtx not valid.", __func__);
19488 }
19489
Hoonki Lee27511902013-03-14 18:19:06 -070019490 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019491 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019493 "%s: TDLS mode is disabled OR not enabled in FW."
19494 MAC_ADDRESS_STR " action %d declined.",
19495 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019496 return -ENOTSUPP;
19497 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019498
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019499 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19500
19501 if( NULL == pHddStaCtx )
19502 {
19503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19504 "%s: HDD station context NULL ",__func__);
19505 return -EINVAL;
19506 }
19507
19508 /* STA should be connected and authenticated
19509 * before sending any TDLS frames
19510 */
19511 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19512 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19513 {
19514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19515 "STA is not connected or unauthenticated. "
19516 "connState %u, uIsAuthenticated %u",
19517 pHddStaCtx->conn_info.connState,
19518 pHddStaCtx->conn_info.uIsAuthenticated);
19519 return -EAGAIN;
19520 }
19521
Hoonki Lee27511902013-03-14 18:19:06 -070019522 /* other than teardown frame, other mgmt frames are not sent if disabled */
19523 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19524 {
19525 /* if tdls_mode is disabled to respond to peer's request */
19526 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19527 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019529 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019530 " TDLS mode is disabled. action %d declined.",
19531 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019532
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019533 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019534 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019535
19536 if (vos_max_concurrent_connections_reached())
19537 {
19538 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19539 return -EINVAL;
19540 }
Hoonki Lee27511902013-03-14 18:19:06 -070019541 }
19542
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019543 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19544 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019545 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019546 {
19547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019548 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019549 " TDLS setup is ongoing. action %d declined.",
19550 __func__, MAC_ADDR_ARRAY(peer), action_code);
19551 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019552 }
19553 }
19554
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019555 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19556 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019557 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019558 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19559 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019560 {
19561 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19562 we return error code at 'add_station()'. Hence we have this
19563 check again in addtion to add_station().
19564 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019565 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019566 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19568 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019569 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19570 __func__, MAC_ADDR_ARRAY(peer), action_code,
19571 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019572 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019573 }
19574 else
19575 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019576 /* maximum reached. tweak to send error code to peer and return
19577 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019578 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19580 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019581 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19582 __func__, MAC_ADDR_ARRAY(peer), status_code,
19583 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019584 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019585 /* fall through to send setup resp with failure status
19586 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019587 }
19588 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019589 else
19590 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019591 mutex_lock(&pHddCtx->tdls_lock);
19592 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019593 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019594 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019595 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019597 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19598 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019599 return -EPERM;
19600 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019601 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019602 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019603 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019604
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019606 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019607 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19608 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019609
Hoonki Leea34dd892013-02-05 22:56:02 -080019610 /*Except teardown responder will not be used so just make 0*/
19611 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019612 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019613 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019614
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019615 mutex_lock(&pHddCtx->tdls_lock);
19616 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019617
19618 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19619 responder = pTdlsPeer->is_responder;
19620 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019621 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019623 "%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 -070019624 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19625 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019626 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019627 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019628 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019629 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019630 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019631
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019632 /* Discard TDLS setup if peer is removed by user app */
19633 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19634 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19635 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19636 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19637
19638 mutex_lock(&pHddCtx->tdls_lock);
19639 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19640 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19641 mutex_unlock(&pHddCtx->tdls_lock);
19642 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19643 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19644 MAC_ADDR_ARRAY(peer), action_code);
19645 return -EINVAL;
19646 }
19647 mutex_unlock(&pHddCtx->tdls_lock);
19648 }
19649
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019650 /* For explicit trigger of DIS_REQ come out of BMPS for
19651 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019652 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019653 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019654 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19655 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019656 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019657 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019659 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19660 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019661 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19662 if (status != VOS_STATUS_SUCCESS) {
19663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019664 } else {
19665 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019666 }
Hoonki Lee14621352013-04-16 17:51:19 -070019667 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019668 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019669 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19671 }
19672 }
Hoonki Lee14621352013-04-16 17:51:19 -070019673 }
19674
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019675 /* make sure doesn't call send_mgmt() while it is pending */
19676 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19677 {
19678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019679 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019680 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019681 ret = -EBUSY;
19682 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019683 }
19684
19685 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019686 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19687
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019688 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19689 pAdapter->sessionId, peer, action_code, dialog_token,
19690 status_code, peer_capability, (tANI_U8 *)buf, len,
19691 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019692
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019693 if (VOS_STATUS_SUCCESS != status)
19694 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19696 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019697 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019698 ret = -EINVAL;
19699 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019700 }
19701
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019702 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19703 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19704 WAIT_TIME_TDLS_MGMT);
19705
Hoonki Leed37cbb32013-04-20 00:31:14 -070019706 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19707 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19708
19709 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019710 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019712 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019713 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019714 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019715
19716 if (pHddCtx->isLogpInProgress)
19717 {
19718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19719 "%s: LOGP in Progress. Ignore!!!", __func__);
19720 return -EAGAIN;
19721 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019722 if (rc <= 0)
19723 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19724 WLAN_LOG_INDICATOR_HOST_DRIVER,
19725 WLAN_LOG_REASON_HDD_TIME_OUT,
19726 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019727
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019728 ret = -EINVAL;
19729 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019730 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019731 else
19732 {
19733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19734 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19735 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19736 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019737
Gopichand Nakkala05922802013-03-14 12:23:19 -070019738 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019739 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019740 ret = max_sta_failed;
19741 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019742 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019743
Hoonki Leea34dd892013-02-05 22:56:02 -080019744 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19745 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019746 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19748 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019749 }
19750 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19751 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019752 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19754 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019755 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019756
19757 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019758
19759tx_failed:
19760 /* add_station will be called before sending TDLS_SETUP_REQ and
19761 * TDLS_SETUP_RSP and as part of add_station driver will enable
19762 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19763 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19764 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19765 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19766 */
19767
19768 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19769 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19770 wlan_hdd_tdls_check_bmps(pAdapter);
19771 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019772}
19773
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019774#if TDLS_MGMT_VERSION2
19775static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19776 u8 *peer, u8 action_code, u8 dialog_token,
19777 u16 status_code, u32 peer_capability,
19778 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019779#else /* TDLS_MGMT_VERSION2 */
19780#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19781static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19782 struct net_device *dev,
19783 const u8 *peer, u8 action_code,
19784 u8 dialog_token, u16 status_code,
19785 u32 peer_capability, bool initiator,
19786 const u8 *buf, size_t len)
19787#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19788static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19789 struct net_device *dev,
19790 const u8 *peer, u8 action_code,
19791 u8 dialog_token, u16 status_code,
19792 u32 peer_capability, const u8 *buf,
19793 size_t len)
19794#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19795static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19796 struct net_device *dev,
19797 u8 *peer, u8 action_code,
19798 u8 dialog_token,
19799 u16 status_code, u32 peer_capability,
19800 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019801#else
19802static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19803 u8 *peer, u8 action_code, u8 dialog_token,
19804 u16 status_code, const u8 *buf, size_t len)
19805#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019806#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019807{
19808 int ret;
19809
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019810 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019811#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019812 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19813 dialog_token, status_code,
19814 peer_capability, buf, len);
19815#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019816#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19817 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019818 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19819 dialog_token, status_code,
19820 peer_capability, initiator,
19821 buf, len);
19822#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19823 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19824 dialog_token, status_code,
19825 peer_capability, buf, len);
19826#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19827 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19828 dialog_token, status_code,
19829 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019830#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019831 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19832 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019833#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019834#endif
19835 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019836
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019837 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019838}
Atul Mittal115287b2014-07-08 13:26:33 +053019839
19840int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19842 const u8 *peer,
19843#else
Atul Mittal115287b2014-07-08 13:26:33 +053019844 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019845#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019846 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019847 cfg80211_exttdls_callback callback)
19848{
19849
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019850 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019851 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019852 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19854 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19855 __func__, MAC_ADDR_ARRAY(peer));
19856
19857 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19858 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19859
19860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019861 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19862 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19863 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019864 return -ENOTSUPP;
19865 }
19866
19867 /* To cater the requirement of establishing the TDLS link
19868 * irrespective of the data traffic , get an entry of TDLS peer.
19869 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019870 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019871 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19872 if (pTdlsPeer == NULL) {
19873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19874 "%s: peer " MAC_ADDRESS_STR " not existing",
19875 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019876 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019877 return -EINVAL;
19878 }
19879
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019880 /* check FW TDLS Off Channel capability */
19881 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019882 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019883 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019884 {
19885 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19886 pTdlsPeer->peerParams.global_operating_class =
19887 tdls_peer_params->global_operating_class;
19888 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19889 pTdlsPeer->peerParams.min_bandwidth_kbps =
19890 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019891 /* check configured channel is valid, non dfs and
19892 * not current operating channel */
19893 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19894 tdls_peer_params->channel)) &&
19895 (pHddStaCtx) &&
19896 (tdls_peer_params->channel !=
19897 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019898 {
19899 pTdlsPeer->isOffChannelConfigured = TRUE;
19900 }
19901 else
19902 {
19903 pTdlsPeer->isOffChannelConfigured = FALSE;
19904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19905 "%s: Configured Tdls Off Channel is not valid", __func__);
19906
19907 }
19908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019909 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19910 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019911 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019912 pTdlsPeer->isOffChannelConfigured,
19913 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019914 }
19915 else
19916 {
19917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019918 "%s: TDLS off channel FW capability %d, "
19919 "host capab %d or Invalid TDLS Peer Params", __func__,
19920 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19921 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019922 }
19923
Atul Mittal115287b2014-07-08 13:26:33 +053019924 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19925
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019926 mutex_unlock(&pHddCtx->tdls_lock);
19927
Atul Mittal115287b2014-07-08 13:26:33 +053019928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19929 " %s TDLS Add Force Peer Failed",
19930 __func__);
19931 return -EINVAL;
19932 }
19933 /*EXT TDLS*/
19934
19935 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019936 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19938 " %s TDLS set callback Failed",
19939 __func__);
19940 return -EINVAL;
19941 }
19942
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019943 mutex_unlock(&pHddCtx->tdls_lock);
19944
Atul Mittal115287b2014-07-08 13:26:33 +053019945 return(0);
19946
19947}
19948
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019949int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19951 const u8 *peer
19952#else
19953 u8 *peer
19954#endif
19955)
Atul Mittal115287b2014-07-08 13:26:33 +053019956{
19957
19958 hddTdlsPeer_t *pTdlsPeer;
19959 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019960
Atul Mittal115287b2014-07-08 13:26:33 +053019961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19962 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19963 __func__, MAC_ADDR_ARRAY(peer));
19964
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019965 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19967 return -EINVAL;
19968 }
19969
Atul Mittal115287b2014-07-08 13:26:33 +053019970 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19971 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19972
19973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019974 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19975 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19976 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019977 return -ENOTSUPP;
19978 }
19979
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019980 mutex_lock(&pHddCtx->tdls_lock);
19981 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019982
19983 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019984 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019986 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019987 __func__, MAC_ADDR_ARRAY(peer));
19988 return -EINVAL;
19989 }
19990 else {
19991 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19992 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019993 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19994 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019995 /* if channel switch is configured, reset
19996 the channel for this peer */
19997 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19998 {
19999 pTdlsPeer->peerParams.channel = 0;
20000 pTdlsPeer->isOffChannelConfigured = FALSE;
20001 }
Atul Mittal115287b2014-07-08 13:26:33 +053020002 }
20003
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020004 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020005 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020006 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020007 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020008 }
Atul Mittal115287b2014-07-08 13:26:33 +053020009
20010 /*EXT TDLS*/
20011
20012 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020013 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20015 " %s TDLS set callback Failed",
20016 __func__);
20017 return -EINVAL;
20018 }
Atul Mittal115287b2014-07-08 13:26:33 +053020019
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020020 mutex_unlock(&pHddCtx->tdls_lock);
20021
20022 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020023}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020024static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20026 const u8 *peer,
20027#else
20028 u8 *peer,
20029#endif
20030 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020031{
20032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20033 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020034 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020035 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020037 ENTER();
20038
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020039 if (!pAdapter) {
20040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20041 return -EINVAL;
20042 }
20043
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020044 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20045 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20046 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020047 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020048 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020050 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020051 return -EINVAL;
20052 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020053
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020054 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020055 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020057 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020058 }
20059
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020060
20061 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020062 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020063 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020065 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20066 "Cannot process TDLS commands",
20067 pHddCtx->cfg_ini->fEnableTDLSSupport,
20068 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020069 return -ENOTSUPP;
20070 }
20071
20072 switch (oper) {
20073 case NL80211_TDLS_ENABLE_LINK:
20074 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020075 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020076 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020077 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20078 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020079 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020080 tANI_U16 numCurrTdlsPeers = 0;
20081 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020082 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020083 tSirMacAddr peerMac;
20084 int channel;
20085 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020086
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20088 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20089 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020090
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020091 mutex_lock(&pHddCtx->tdls_lock);
20092 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020093 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020094 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020095 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20097 " (oper %d) not exsting. ignored",
20098 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20099 return -EINVAL;
20100 }
20101
20102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20103 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20104 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20105 "NL80211_TDLS_ENABLE_LINK");
20106
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020107 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20108 {
20109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20110 MAC_ADDRESS_STR " failed",
20111 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020112 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020113 return -EINVAL;
20114 }
20115
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020116 /* before starting tdls connection, set tdls
20117 * off channel established status to default value */
20118 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020119
20120 mutex_unlock(&pHddCtx->tdls_lock);
20121
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020122 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020123 /* TDLS Off Channel, Disable tdls channel switch,
20124 when there are more than one tdls link */
20125 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020126 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020127 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020128 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020129 /* get connected peer and send disable tdls off chan */
20130 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020131 if ((connPeer) &&
20132 (connPeer->isOffChannelSupported == TRUE) &&
20133 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020134 {
20135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20136 "%s: More then one peer connected, Disable "
20137 "TDLS channel switch", __func__);
20138
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020139 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020140 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20141 channel = connPeer->peerParams.channel;
20142
20143 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020144
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020145 ret = sme_SendTdlsChanSwitchReq(
20146 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020147 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020148 peerMac,
20149 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020150 TDLS_OFF_CHANNEL_BW_OFFSET,
20151 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020152 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020153 hddLog(VOS_TRACE_LEVEL_ERROR,
20154 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020155 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020156 }
20157 else
20158 {
20159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20160 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020161 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020162 "isOffChannelConfigured %d",
20163 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020164 (connPeer ? (connPeer->isOffChannelSupported)
20165 : -1),
20166 (connPeer ? (connPeer->isOffChannelConfigured)
20167 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020168 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020169 }
20170 }
20171
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020172 mutex_lock(&pHddCtx->tdls_lock);
20173 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20174 if ( NULL == pTdlsPeer ) {
20175 mutex_unlock(&pHddCtx->tdls_lock);
20176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20177 "%s: " MAC_ADDRESS_STR
20178 " (oper %d) peer got freed in other context. ignored",
20179 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20180 return -EINVAL;
20181 }
20182 peer_status = pTdlsPeer->link_status;
20183 mutex_unlock(&pHddCtx->tdls_lock);
20184
20185 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020186 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020187 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020188
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020189 if (0 != wlan_hdd_tdls_get_link_establish_params(
20190 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020192 return -EINVAL;
20193 }
20194 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020195
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020196 ret = sme_SendTdlsLinkEstablishParams(
20197 WLAN_HDD_GET_HAL_CTX(pAdapter),
20198 pAdapter->sessionId, peer,
20199 &tdlsLinkEstablishParams);
20200 if (ret != VOS_STATUS_SUCCESS) {
20201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20202 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020203 /* Send TDLS peer UAPSD capabilities to the firmware and
20204 * register with the TL on after the response for this operation
20205 * is received .
20206 */
20207 ret = wait_for_completion_interruptible_timeout(
20208 &pAdapter->tdls_link_establish_req_comp,
20209 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020210
20211 mutex_lock(&pHddCtx->tdls_lock);
20212 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20213 if ( NULL == pTdlsPeer ) {
20214 mutex_unlock(&pHddCtx->tdls_lock);
20215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20216 "%s %d: " MAC_ADDRESS_STR
20217 " (oper %d) peer got freed in other context. ignored",
20218 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20219 (int)oper);
20220 return -EINVAL;
20221 }
20222 peer_status = pTdlsPeer->link_status;
20223 mutex_unlock(&pHddCtx->tdls_lock);
20224
20225 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020226 {
20227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020228 FL("Link Establish Request Failed Status %ld"),
20229 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020230 return -EINVAL;
20231 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020232 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020233
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020234 mutex_lock(&pHddCtx->tdls_lock);
20235 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20236 if ( NULL == pTdlsPeer ) {
20237 mutex_unlock(&pHddCtx->tdls_lock);
20238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20239 "%s: " MAC_ADDRESS_STR
20240 " (oper %d) peer got freed in other context. ignored",
20241 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20242 return -EINVAL;
20243 }
20244
Atul Mittal115287b2014-07-08 13:26:33 +053020245 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20246 eTDLS_LINK_CONNECTED,
20247 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020248 staDesc.ucSTAId = pTdlsPeer->staId;
20249 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020250
20251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20252 "%s: tdlsLinkEstablishParams of peer "
20253 MAC_ADDRESS_STR "uapsdQueues: %d"
20254 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20255 "isResponder: %d peerstaId: %d",
20256 __func__,
20257 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20258 tdlsLinkEstablishParams.uapsdQueues,
20259 tdlsLinkEstablishParams.qos,
20260 tdlsLinkEstablishParams.maxSp,
20261 tdlsLinkEstablishParams.isBufSta,
20262 tdlsLinkEstablishParams.isOffChannelSupported,
20263 tdlsLinkEstablishParams.isResponder,
20264 pTdlsPeer->staId);
20265
20266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20267 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20268 __func__,
20269 staDesc.ucSTAId,
20270 staDesc.ucQosEnabled);
20271
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020272 ret = WLANTL_UpdateTdlsSTAClient(
20273 pHddCtx->pvosContext,
20274 &staDesc);
20275 if (ret != VOS_STATUS_SUCCESS) {
20276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20277 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020278
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020279 /* Mark TDLS client Authenticated .*/
20280 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20281 pTdlsPeer->staId,
20282 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020283 if (VOS_STATUS_SUCCESS == status)
20284 {
Hoonki Lee14621352013-04-16 17:51:19 -070020285 if (pTdlsPeer->is_responder == 0)
20286 {
20287 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020288 tdlsConnInfo_t *tdlsInfo;
20289
20290 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20291
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020292 if (!vos_timer_is_initialized(
20293 &pTdlsPeer->initiatorWaitTimeoutTimer))
20294 {
20295 /* Initialize initiator wait callback */
20296 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020297 &pTdlsPeer->initiatorWaitTimeoutTimer,
20298 VOS_TIMER_TYPE_SW,
20299 wlan_hdd_tdls_initiator_wait_cb,
20300 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020301 }
Hoonki Lee14621352013-04-16 17:51:19 -070020302 wlan_hdd_tdls_timer_restart(pAdapter,
20303 &pTdlsPeer->initiatorWaitTimeoutTimer,
20304 WAIT_TIME_TDLS_INITIATOR);
20305 /* suspend initiator TX until it receives direct packet from the
20306 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020307 ret = WLANTL_SuspendDataTx(
20308 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20309 &staId, NULL);
20310 if (ret != VOS_STATUS_SUCCESS) {
20311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20312 }
Hoonki Lee14621352013-04-16 17:51:19 -070020313 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020314
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020315 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020316 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020317 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020318 suppChannelLen =
20319 tdlsLinkEstablishParams.supportedChannelsLen;
20320
20321 if ((suppChannelLen > 0) &&
20322 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20323 {
20324 tANI_U8 suppPeerChannel = 0;
20325 int i = 0;
20326 for (i = 0U; i < suppChannelLen; i++)
20327 {
20328 suppPeerChannel =
20329 tdlsLinkEstablishParams.supportedChannels[i];
20330
20331 pTdlsPeer->isOffChannelSupported = FALSE;
20332 if (suppPeerChannel ==
20333 pTdlsPeer->peerParams.channel)
20334 {
20335 pTdlsPeer->isOffChannelSupported = TRUE;
20336 break;
20337 }
20338 }
20339 }
20340 else
20341 {
20342 pTdlsPeer->isOffChannelSupported = FALSE;
20343 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020344 }
20345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20346 "%s: TDLS channel switch request for channel "
20347 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020348 "%d isOffChannelSupported %d", __func__,
20349 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020350 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020351 suppChannelLen,
20352 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020353
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020354 /* TDLS Off Channel, Enable tdls channel switch,
20355 when their is only one tdls link and it supports */
20356 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20357 if ((numCurrTdlsPeers == 1) &&
20358 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20359 (TRUE == pTdlsPeer->isOffChannelConfigured))
20360 {
20361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20362 "%s: Send TDLS channel switch request for channel %d",
20363 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020364
20365 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020366 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20367 channel = pTdlsPeer->peerParams.channel;
20368
20369 mutex_unlock(&pHddCtx->tdls_lock);
20370
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020371 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20372 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020373 peerMac,
20374 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020375 TDLS_OFF_CHANNEL_BW_OFFSET,
20376 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020377 if (ret != VOS_STATUS_SUCCESS) {
20378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20379 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020380 }
20381 else
20382 {
20383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20384 "%s: TDLS channel switch request not sent"
20385 " numCurrTdlsPeers %d "
20386 "isOffChannelSupported %d "
20387 "isOffChannelConfigured %d",
20388 __func__, numCurrTdlsPeers,
20389 pTdlsPeer->isOffChannelSupported,
20390 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020391 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020392 }
20393
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020394 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020395 else
20396 mutex_unlock(&pHddCtx->tdls_lock);
20397
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020398 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020399
20400 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020401 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20402 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020403 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020404 int ac;
20405 uint8 ucAc[4] = { WLANTL_AC_VO,
20406 WLANTL_AC_VI,
20407 WLANTL_AC_BK,
20408 WLANTL_AC_BE };
20409 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20410 for(ac=0; ac < 4; ac++)
20411 {
20412 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20413 pTdlsPeer->staId, ucAc[ac],
20414 tlTid[ac], tlTid[ac], 0, 0,
20415 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020416 if (status != VOS_STATUS_SUCCESS) {
20417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20418 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020419 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020420 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020421 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020422
Bhargav Shah66896792015-10-01 18:17:37 +053020423 /* stop TCP delack timer if TDLS is enable */
20424 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20425 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020426 hdd_wlan_tdls_enable_link_event(peer,
20427 pTdlsPeer->isOffChannelSupported,
20428 pTdlsPeer->isOffChannelConfigured,
20429 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020430 }
20431 break;
20432 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020433 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020434 tANI_U16 numCurrTdlsPeers = 0;
20435 hddTdlsPeer_t *connPeer = NULL;
20436
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20438 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20439 __func__, MAC_ADDR_ARRAY(peer));
20440
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020441 mutex_lock(&pHddCtx->tdls_lock);
20442 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020443
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020444
Sunil Dutt41de4e22013-11-14 18:09:02 +053020445 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020446 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20448 " (oper %d) not exsting. ignored",
20449 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20450 return -EINVAL;
20451 }
20452
20453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20454 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20455 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20456 "NL80211_TDLS_DISABLE_LINK");
20457
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020458 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020459 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020460 long status;
20461
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020462 /* set tdls off channel status to false for this peer */
20463 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020464 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20465 eTDLS_LINK_TEARING,
20466 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20467 eTDLS_LINK_UNSPECIFIED:
20468 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020469 mutex_unlock(&pHddCtx->tdls_lock);
20470
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020471 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20472
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020473 status = sme_DeleteTdlsPeerSta(
20474 WLAN_HDD_GET_HAL_CTX(pAdapter),
20475 pAdapter->sessionId, peer );
20476 if (status != VOS_STATUS_SUCCESS) {
20477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20478 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020479
20480 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20481 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020482
20483 mutex_lock(&pHddCtx->tdls_lock);
20484 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20485 if ( NULL == pTdlsPeer ) {
20486 mutex_unlock(&pHddCtx->tdls_lock);
20487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20488 " peer was freed in other context",
20489 __func__, MAC_ADDR_ARRAY(peer));
20490 return -EINVAL;
20491 }
20492
Atul Mittal271a7652014-09-12 13:18:22 +053020493 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020494 eTDLS_LINK_IDLE,
20495 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020496 mutex_unlock(&pHddCtx->tdls_lock);
20497
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020498 if (status <= 0)
20499 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20501 "%s: Del station failed status %ld",
20502 __func__, status);
20503 return -EPERM;
20504 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020505
20506 /* TDLS Off Channel, Enable tdls channel switch,
20507 when their is only one tdls link and it supports */
20508 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20509 if (numCurrTdlsPeers == 1)
20510 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020511 tSirMacAddr peerMac;
20512 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020513
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020514 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020515 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020516
20517 if (connPeer == NULL) {
20518 mutex_unlock(&pHddCtx->tdls_lock);
20519 hddLog(VOS_TRACE_LEVEL_ERROR,
20520 "%s connPeer is NULL", __func__);
20521 return -EINVAL;
20522 }
20523
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020524 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20525 channel = connPeer->peerParams.channel;
20526
20527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20528 "%s: TDLS channel switch "
20529 "isOffChannelSupported %d "
20530 "isOffChannelConfigured %d "
20531 "isOffChannelEstablished %d",
20532 __func__,
20533 (connPeer ? connPeer->isOffChannelSupported : -1),
20534 (connPeer ? connPeer->isOffChannelConfigured : -1),
20535 (connPeer ? connPeer->isOffChannelEstablished : -1));
20536
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020537 if ((connPeer) &&
20538 (connPeer->isOffChannelSupported == TRUE) &&
20539 (connPeer->isOffChannelConfigured == TRUE))
20540 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020541 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020542 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020543 status = sme_SendTdlsChanSwitchReq(
20544 WLAN_HDD_GET_HAL_CTX(pAdapter),
20545 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020546 peerMac,
20547 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020548 TDLS_OFF_CHANNEL_BW_OFFSET,
20549 TDLS_CHANNEL_SWITCH_ENABLE);
20550 if (status != VOS_STATUS_SUCCESS) {
20551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20552 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020553 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020554 else
20555 mutex_unlock(&pHddCtx->tdls_lock);
20556 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020557 else
20558 {
20559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20560 "%s: TDLS channel switch request not sent "
20561 "numCurrTdlsPeers %d ",
20562 __func__, numCurrTdlsPeers);
20563 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020564 }
20565 else
20566 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020567 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20569 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020570 }
Bhargav Shah66896792015-10-01 18:17:37 +053020571 if (numCurrTdlsPeers == 0) {
20572 /* start TCP delack timer if TDLS is disable */
20573 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20574 hdd_manage_delack_timer(pHddCtx);
20575 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020576 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020577 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020578 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020579 {
Atul Mittal115287b2014-07-08 13:26:33 +053020580 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020581
Atul Mittal115287b2014-07-08 13:26:33 +053020582 if (0 != status)
20583 {
20584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020585 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020586 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020587 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020588 break;
20589 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020590 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020591 {
Atul Mittal115287b2014-07-08 13:26:33 +053020592 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20593 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020594 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020595 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020596
Atul Mittal115287b2014-07-08 13:26:33 +053020597 if (0 != status)
20598 {
20599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020600 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020601 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020602 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020603 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020604 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020605 case NL80211_TDLS_DISCOVERY_REQ:
20606 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020608 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020609 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020610 return -ENOTSUPP;
20611 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20613 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020614 return -ENOTSUPP;
20615 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020616
20617 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020618 return 0;
20619}
Chilam NG571c65a2013-01-19 12:27:36 +053020620
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020621static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20623 const u8 *peer,
20624#else
20625 u8 *peer,
20626#endif
20627 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020628{
20629 int ret;
20630
20631 vos_ssr_protect(__func__);
20632 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20633 vos_ssr_unprotect(__func__);
20634
20635 return ret;
20636}
20637
Chilam NG571c65a2013-01-19 12:27:36 +053020638int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20639 struct net_device *dev, u8 *peer)
20640{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020641 hddLog(VOS_TRACE_LEVEL_INFO,
20642 "tdls send discover req: "MAC_ADDRESS_STR,
20643 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020644#if TDLS_MGMT_VERSION2
20645 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20646 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20647#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020648#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20649 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20650 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20651#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20652 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20653 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20654#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20655 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20656 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20657#else
Chilam NG571c65a2013-01-19 12:27:36 +053020658 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20659 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020660#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020661#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020662}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020663#endif
20664
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020665#ifdef WLAN_FEATURE_GTK_OFFLOAD
20666/*
20667 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20668 * Callback rountine called upon receiving response for
20669 * get offload info
20670 */
20671void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20672 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20673{
20674
20675 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020676 tANI_U8 tempReplayCounter[8];
20677 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020678
20679 ENTER();
20680
20681 if (NULL == pAdapter)
20682 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020684 "%s: HDD adapter is Null", __func__);
20685 return ;
20686 }
20687
20688 if (NULL == pGtkOffloadGetInfoRsp)
20689 {
20690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20691 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20692 return ;
20693 }
20694
20695 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20696 {
20697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20698 "%s: wlan Failed to get replay counter value",
20699 __func__);
20700 return ;
20701 }
20702
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020703 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20704 /* Update replay counter */
20705 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20706 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20707
20708 {
20709 /* changing from little to big endian since supplicant
20710 * works on big endian format
20711 */
20712 int i;
20713 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20714
20715 for (i = 0; i < 8; i++)
20716 {
20717 tempReplayCounter[7-i] = (tANI_U8)p[i];
20718 }
20719 }
20720
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020721 /* Update replay counter to NL */
20722 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020723 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020724}
20725
20726/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020727 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020728 * This function is used to offload GTK rekeying job to the firmware.
20729 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020730int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020731 struct cfg80211_gtk_rekey_data *data)
20732{
20733 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20734 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20735 hdd_station_ctx_t *pHddStaCtx;
20736 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020737 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020738 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020739 eHalStatus status = eHAL_STATUS_FAILURE;
20740
20741 ENTER();
20742
20743 if (NULL == pAdapter)
20744 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020746 "%s: HDD adapter is Null", __func__);
20747 return -ENODEV;
20748 }
20749
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020750 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20751 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20752 pAdapter->sessionId, pAdapter->device_mode));
20753
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020754 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020755 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020756 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020757 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020758 }
20759
20760 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20761 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20762 if (NULL == hHal)
20763 {
20764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20765 "%s: HAL context is Null!!!", __func__);
20766 return -EAGAIN;
20767 }
20768
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020769 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20770 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20771 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20772 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020773 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020774 {
20775 /* changing from big to little endian since driver
20776 * works on little endian format
20777 */
20778 tANI_U8 *p =
20779 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20780 int i;
20781
20782 for (i = 0; i < 8; i++)
20783 {
20784 p[7-i] = data->replay_ctr[i];
20785 }
20786 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020787
20788 if (TRUE == pHddCtx->hdd_wlan_suspended)
20789 {
20790 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020791 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20792 sizeof (tSirGtkOffloadParams));
20793 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020794 pAdapter->sessionId);
20795
20796 if (eHAL_STATUS_SUCCESS != status)
20797 {
20798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20799 "%s: sme_SetGTKOffload failed, returned %d",
20800 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020801
20802 /* Need to clear any trace of key value in the memory.
20803 * Thus zero out the memory even though it is local
20804 * variable.
20805 */
20806 vos_mem_zero(&hddGtkOffloadReqParams,
20807 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020808 return status;
20809 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20811 "%s: sme_SetGTKOffload successfull", __func__);
20812 }
20813 else
20814 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20816 "%s: wlan not suspended GTKOffload request is stored",
20817 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020818 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020819
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020820 /* Need to clear any trace of key value in the memory.
20821 * Thus zero out the memory even though it is local
20822 * variable.
20823 */
20824 vos_mem_zero(&hddGtkOffloadReqParams,
20825 sizeof(hddGtkOffloadReqParams));
20826
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020827 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020828 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020829}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020830
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020831int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20832 struct cfg80211_gtk_rekey_data *data)
20833{
20834 int ret;
20835
20836 vos_ssr_protect(__func__);
20837 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20838 vos_ssr_unprotect(__func__);
20839
20840 return ret;
20841}
20842#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020843/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020844 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020845 * This function is used to set access control policy
20846 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020847static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20848 struct net_device *dev,
20849 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020850{
20851 int i;
20852 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20853 hdd_hostapd_state_t *pHostapdState;
20854 tsap_Config_t *pConfig;
20855 v_CONTEXT_t pVosContext = NULL;
20856 hdd_context_t *pHddCtx;
20857 int status;
20858
20859 ENTER();
20860
20861 if (NULL == pAdapter)
20862 {
20863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20864 "%s: HDD adapter is Null", __func__);
20865 return -ENODEV;
20866 }
20867
20868 if (NULL == params)
20869 {
20870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20871 "%s: params is Null", __func__);
20872 return -EINVAL;
20873 }
20874
20875 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20876 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020877 if (0 != status)
20878 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020879 return status;
20880 }
20881
20882 pVosContext = pHddCtx->pvosContext;
20883 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20884
20885 if (NULL == pHostapdState)
20886 {
20887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20888 "%s: pHostapdState is Null", __func__);
20889 return -EINVAL;
20890 }
20891
20892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20893 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020894 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20895 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20896 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020897
20898 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20899 {
20900 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20901
20902 /* default value */
20903 pConfig->num_accept_mac = 0;
20904 pConfig->num_deny_mac = 0;
20905
20906 /**
20907 * access control policy
20908 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20909 * listed in hostapd.deny file.
20910 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20911 * listed in hostapd.accept file.
20912 */
20913 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20914 {
20915 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20916 }
20917 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20918 {
20919 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20920 }
20921 else
20922 {
20923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20924 "%s:Acl Policy : %d is not supported",
20925 __func__, params->acl_policy);
20926 return -ENOTSUPP;
20927 }
20928
20929 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20930 {
20931 pConfig->num_accept_mac = params->n_acl_entries;
20932 for (i = 0; i < params->n_acl_entries; i++)
20933 {
20934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20935 "** Add ACL MAC entry %i in WhiletList :"
20936 MAC_ADDRESS_STR, i,
20937 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20938
20939 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20940 sizeof(qcmacaddr));
20941 }
20942 }
20943 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20944 {
20945 pConfig->num_deny_mac = params->n_acl_entries;
20946 for (i = 0; i < params->n_acl_entries; i++)
20947 {
20948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20949 "** Add ACL MAC entry %i in BlackList :"
20950 MAC_ADDRESS_STR, i,
20951 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20952
20953 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20954 sizeof(qcmacaddr));
20955 }
20956 }
20957
20958 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20959 {
20960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20961 "%s: SAP Set Mac Acl fail", __func__);
20962 return -EINVAL;
20963 }
20964 }
20965 else
20966 {
20967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020968 "%s: Invalid device_mode = %s (%d)",
20969 __func__, hdd_device_modetoString(pAdapter->device_mode),
20970 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020971 return -EINVAL;
20972 }
20973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020974 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020975 return 0;
20976}
20977
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020978static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20979 struct net_device *dev,
20980 const struct cfg80211_acl_data *params)
20981{
20982 int ret;
20983 vos_ssr_protect(__func__);
20984 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20985 vos_ssr_unprotect(__func__);
20986
20987 return ret;
20988}
20989
Leo Chang9056f462013-08-01 19:21:11 -070020990#ifdef WLAN_NL80211_TESTMODE
20991#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020992void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020993(
20994 void *pAdapter,
20995 void *indCont
20996)
20997{
Leo Changd9df8aa2013-09-26 13:32:26 -070020998 tSirLPHBInd *lphbInd;
20999 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021000 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021001
21002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021003 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021004
c_hpothu73f35e62014-04-18 13:40:08 +053021005 if (pAdapter == NULL)
21006 {
21007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21008 "%s: pAdapter is NULL\n",__func__);
21009 return;
21010 }
21011
Leo Chang9056f462013-08-01 19:21:11 -070021012 if (NULL == indCont)
21013 {
21014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021015 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021016 return;
21017 }
21018
c_hpothu73f35e62014-04-18 13:40:08 +053021019 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021020 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021021 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021022 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021023 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021024 GFP_ATOMIC);
21025 if (!skb)
21026 {
21027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21028 "LPHB timeout, NL buffer alloc fail");
21029 return;
21030 }
21031
Leo Changac3ba772013-10-07 09:47:04 -070021032 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021033 {
21034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21035 "WLAN_HDD_TM_ATTR_CMD put fail");
21036 goto nla_put_failure;
21037 }
Leo Changac3ba772013-10-07 09:47:04 -070021038 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021039 {
21040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21041 "WLAN_HDD_TM_ATTR_TYPE put fail");
21042 goto nla_put_failure;
21043 }
Leo Changac3ba772013-10-07 09:47:04 -070021044 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021045 sizeof(tSirLPHBInd), lphbInd))
21046 {
21047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21048 "WLAN_HDD_TM_ATTR_DATA put fail");
21049 goto nla_put_failure;
21050 }
Leo Chang9056f462013-08-01 19:21:11 -070021051 cfg80211_testmode_event(skb, GFP_ATOMIC);
21052 return;
21053
21054nla_put_failure:
21055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21056 "NLA Put fail");
21057 kfree_skb(skb);
21058
21059 return;
21060}
21061#endif /* FEATURE_WLAN_LPHB */
21062
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021063static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021064{
21065 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21066 int err = 0;
21067#ifdef FEATURE_WLAN_LPHB
21068 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021069 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021070
21071 ENTER();
21072
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021073 err = wlan_hdd_validate_context(pHddCtx);
21074 if (0 != err)
21075 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021076 return err;
21077 }
Leo Chang9056f462013-08-01 19:21:11 -070021078#endif /* FEATURE_WLAN_LPHB */
21079
21080 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21081 if (err)
21082 {
21083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21084 "%s Testmode INV ATTR", __func__);
21085 return err;
21086 }
21087
21088 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21089 {
21090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21091 "%s Testmode INV CMD", __func__);
21092 return -EINVAL;
21093 }
21094
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21096 TRACE_CODE_HDD_CFG80211_TESTMODE,
21097 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021098 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21099 {
21100#ifdef FEATURE_WLAN_LPHB
21101 /* Low Power Heartbeat configuration request */
21102 case WLAN_HDD_TM_CMD_WLAN_HB:
21103 {
21104 int buf_len;
21105 void *buf;
21106 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021107 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021108
21109 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21110 {
21111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21112 "%s Testmode INV DATA", __func__);
21113 return -EINVAL;
21114 }
21115
21116 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21117 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021118
Manjeet Singh3c577442017-02-10 19:03:38 +053021119 if (buf_len > sizeof(*hb_params)) {
21120 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21121 buf_len);
21122 return -ERANGE;
21123 }
21124
Amar Singhal05852702014-02-04 14:40:00 -080021125 hb_params_temp =(tSirLPHBReq *)buf;
21126 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21127 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21128 return -EINVAL;
21129
Leo Chang9056f462013-08-01 19:21:11 -070021130 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21131 if (NULL == hb_params)
21132 {
21133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21134 "%s Request Buffer Alloc Fail", __func__);
21135 return -EINVAL;
21136 }
21137
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021138 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021139 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021140 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21141 hb_params,
21142 wlan_hdd_cfg80211_lphb_ind_handler);
21143 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021144 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21146 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021147 vos_mem_free(hb_params);
21148 }
Leo Chang9056f462013-08-01 19:21:11 -070021149 return 0;
21150 }
21151#endif /* FEATURE_WLAN_LPHB */
21152 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21154 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021155 return -EOPNOTSUPP;
21156 }
21157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021158 EXIT();
21159 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021160}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021161
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021162static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21163#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21164 struct wireless_dev *wdev,
21165#endif
21166 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021167{
21168 int ret;
21169
21170 vos_ssr_protect(__func__);
21171 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21172 vos_ssr_unprotect(__func__);
21173
21174 return ret;
21175}
Leo Chang9056f462013-08-01 19:21:11 -070021176#endif /* CONFIG_NL80211_TESTMODE */
21177
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021178extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021179static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021180 struct net_device *dev,
21181 int idx, struct survey_info *survey)
21182{
21183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21184 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021185 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021186 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021187 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021188 v_S7_t snr,rssi;
21189 int status, i, j, filled = 0;
21190
21191 ENTER();
21192
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021193 if (NULL == pAdapter)
21194 {
21195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21196 "%s: HDD adapter is Null", __func__);
21197 return -ENODEV;
21198 }
21199
21200 if (NULL == wiphy)
21201 {
21202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21203 "%s: wiphy is Null", __func__);
21204 return -ENODEV;
21205 }
21206
21207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21208 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021209 if (0 != status)
21210 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021211 return status;
21212 }
21213
Mihir Sheted9072e02013-08-21 17:02:29 +053021214 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21215
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021216 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021217 0 != pAdapter->survey_idx ||
21218 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021219 {
21220 /* The survey dump ops when implemented completely is expected to
21221 * return a survey of all channels and the ops is called by the
21222 * kernel with incremental values of the argument 'idx' till it
21223 * returns -ENONET. But we can only support the survey for the
21224 * operating channel for now. survey_idx is used to track
21225 * that the ops is called only once and then return -ENONET for
21226 * the next iteration
21227 */
21228 pAdapter->survey_idx = 0;
21229 return -ENONET;
21230 }
21231
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021232 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21233 {
21234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21235 "%s: Roaming in progress, hence return ", __func__);
21236 return -ENONET;
21237 }
21238
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021239 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21240
21241 wlan_hdd_get_snr(pAdapter, &snr);
21242 wlan_hdd_get_rssi(pAdapter, &rssi);
21243
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21245 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21246 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021247 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21248 hdd_wlan_get_freq(channel, &freq);
21249
21250
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021251 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021252 {
21253 if (NULL == wiphy->bands[i])
21254 {
21255 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21256 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21257 continue;
21258 }
21259
21260 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21261 {
21262 struct ieee80211_supported_band *band = wiphy->bands[i];
21263
21264 if (band->channels[j].center_freq == (v_U16_t)freq)
21265 {
21266 survey->channel = &band->channels[j];
21267 /* The Rx BDs contain SNR values in dB for the received frames
21268 * while the supplicant expects noise. So we calculate and
21269 * return the value of noise (dBm)
21270 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21271 */
21272 survey->noise = rssi - snr;
21273 survey->filled = SURVEY_INFO_NOISE_DBM;
21274 filled = 1;
21275 }
21276 }
21277 }
21278
21279 if (filled)
21280 pAdapter->survey_idx = 1;
21281 else
21282 {
21283 pAdapter->survey_idx = 0;
21284 return -ENONET;
21285 }
21286
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021287 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021288 return 0;
21289}
21290
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021291static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21292 struct net_device *dev,
21293 int idx, struct survey_info *survey)
21294{
21295 int ret;
21296
21297 vos_ssr_protect(__func__);
21298 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21299 vos_ssr_unprotect(__func__);
21300
21301 return ret;
21302}
21303
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021304/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021305 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021306 * this is called when cfg80211 driver resume
21307 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21308 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021309int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021310{
21311 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21312 hdd_adapter_t *pAdapter;
21313 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21314 VOS_STATUS status = VOS_STATUS_SUCCESS;
21315
21316 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021317
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021318 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021319 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021320 return 0;
21321 }
21322
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021323 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21324 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021325
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021326 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021327 {
21328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21329 "%s: Resume SoftAP", __func__);
21330 hdd_set_wlan_suspend_mode(false);
21331 }
21332
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021333 spin_lock(&pHddCtx->schedScan_lock);
21334 pHddCtx->isWiphySuspended = FALSE;
21335 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21336 {
21337 spin_unlock(&pHddCtx->schedScan_lock);
21338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21339 "%s: Return resume is not due to PNO indication", __func__);
21340 return 0;
21341 }
21342 // Reset flag to avoid updatating cfg80211 data old results again
21343 pHddCtx->isSchedScanUpdatePending = FALSE;
21344 spin_unlock(&pHddCtx->schedScan_lock);
21345
21346 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21347
21348 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21349 {
21350 pAdapter = pAdapterNode->pAdapter;
21351 if ( (NULL != pAdapter) &&
21352 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21353 {
21354 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021355 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21357 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021358 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021359 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021360 {
21361 /* Acquire wakelock to handle the case where APP's tries to
21362 * suspend immediately after updating the scan results. Whis
21363 * results in app's is in suspended state and not able to
21364 * process the connect request to AP
21365 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021366 hdd_prevent_suspend_timeout(2000,
21367 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021368 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021369 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021370
21371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21372 "%s : cfg80211 scan result database updated", __func__);
21373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021374 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021375 return 0;
21376
21377 }
21378 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21379 pAdapterNode = pNext;
21380 }
21381
21382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21383 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021384 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021385 return 0;
21386}
21387
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021388int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21389{
21390 int ret;
21391
21392 vos_ssr_protect(__func__);
21393 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21394 vos_ssr_unprotect(__func__);
21395
21396 return ret;
21397}
21398
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021399/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021400 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021401 * this is called when cfg80211 driver suspends
21402 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021403int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021404 struct cfg80211_wowlan *wow)
21405{
21406 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021407 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021408
21409 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021410
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021411 ret = wlan_hdd_validate_context(pHddCtx);
21412 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021413 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021414 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021415 }
21416
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021417 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21419 "%s: Suspend SoftAP", __func__);
21420 hdd_set_wlan_suspend_mode(true);
21421 }
21422
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021423
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021424 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21425 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21426 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021427 pHddCtx->isWiphySuspended = TRUE;
21428
21429 EXIT();
21430
21431 return 0;
21432}
21433
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021434int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21435 struct cfg80211_wowlan *wow)
21436{
21437 int ret;
21438
21439 vos_ssr_protect(__func__);
21440 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21441 vos_ssr_unprotect(__func__);
21442
21443 return ret;
21444}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021445
21446#ifdef FEATURE_OEM_DATA_SUPPORT
21447static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021448 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021449{
21450 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21451
21452 ENTER();
21453
21454 if (wlan_hdd_validate_context(pHddCtx)) {
21455 return;
21456 }
21457 if (!pMsg)
21458 {
21459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21460 return;
21461 }
21462
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021463 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021464
21465 EXIT();
21466 return;
21467
21468}
21469
21470void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021471 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021472{
21473 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21474
21475 ENTER();
21476
21477 if (wlan_hdd_validate_context(pHddCtx)) {
21478 return;
21479 }
21480
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021481 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021482
21483 switch(evType) {
21484 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021485 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021486 break;
21487 default:
21488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21489 break;
21490 }
21491 EXIT();
21492}
21493#endif
21494
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021495#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21496 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021497/**
21498 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21499 * @wiphy: Pointer to wiphy
21500 * @wdev: Pointer to wireless device structure
21501 *
21502 * This function is used to abort an ongoing scan
21503 *
21504 * Return: None
21505 */
21506static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21507 struct wireless_dev *wdev)
21508{
21509 struct net_device *dev = wdev->netdev;
21510 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21511 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21512 int ret;
21513
21514 ENTER();
21515
21516 if (NULL == adapter) {
21517 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21518 return;
21519 }
21520
21521 ret = wlan_hdd_validate_context(hdd_ctx);
21522 if (0 != ret)
21523 return;
21524
21525 wlan_hdd_scan_abort(adapter);
21526
21527 return;
21528}
21529
21530/**
21531 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21532 * @wiphy: Pointer to wiphy
21533 * @wdev: Pointer to wireless device structure
21534 *
21535 * Return: None
21536 */
21537void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21538 struct wireless_dev *wdev)
21539{
21540 vos_ssr_protect(__func__);
21541 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21542 vos_ssr_unprotect(__func__);
21543
21544 return;
21545}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021546#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021547
Abhishek Singh936c6932017-11-07 17:28:23 +053021548#ifdef CHANNEL_SWITCH_SUPPORTED
21549/**
21550 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21551 * channel in SAP/GO
21552 * @wiphy: wiphy pointer
21553 * @dev: dev pointer.
21554 * @csa_params: Change channel params
21555 *
21556 * This function is called to switch channel in SAP/GO
21557 *
21558 * Return: 0 if success else return non zero
21559 */
21560static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21561 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21562{
21563 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21564 hdd_context_t *hdd_ctx;
21565 uint8_t channel;
21566 int ret;
21567 v_CONTEXT_t vos_ctx;
21568
21569 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21570
21571 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21572 ret = wlan_hdd_validate_context(hdd_ctx);
21573 if (ret)
21574 return ret;
21575
21576 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21577 if (!vos_ctx) {
21578 hddLog(LOGE, FL("Vos ctx is null"));
21579 return -EINVAL;
21580 }
21581
21582 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21583 (WLAN_HDD_P2P_GO != adapter->device_mode))
21584 return -ENOTSUPP;
21585
21586 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021587 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021588
21589 return ret;
21590}
21591
21592/**
21593 * wlan_hdd_cfg80211_channel_switch()- function to switch
21594 * channel in SAP/GO
21595 * @wiphy: wiphy pointer
21596 * @dev: dev pointer.
21597 * @csa_params: Change channel params
21598 *
21599 * This function is called to switch channel in SAP/GO
21600 *
21601 * Return: 0 if success else return non zero
21602 */
21603static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21604 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21605{
21606 int ret;
21607
21608 vos_ssr_protect(__func__);
21609 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21610 vos_ssr_unprotect(__func__);
21611
21612 return ret;
21613}
21614#endif
21615
Jeff Johnson295189b2012-06-20 16:38:30 -070021616/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021617static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021618{
21619 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21620 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21621 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21622 .change_station = wlan_hdd_change_station,
21623#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21624 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21625 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21626 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021627#else
21628 .start_ap = wlan_hdd_cfg80211_start_ap,
21629 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21630 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021631#endif
21632 .change_bss = wlan_hdd_cfg80211_change_bss,
21633 .add_key = wlan_hdd_cfg80211_add_key,
21634 .get_key = wlan_hdd_cfg80211_get_key,
21635 .del_key = wlan_hdd_cfg80211_del_key,
21636 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021637#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021638 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021639#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021640 .scan = wlan_hdd_cfg80211_scan,
21641 .connect = wlan_hdd_cfg80211_connect,
21642 .disconnect = wlan_hdd_cfg80211_disconnect,
21643 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21644 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21645 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21646 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21647 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021648 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21649 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021650 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021651#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21652 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21653 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21654 .set_txq_params = wlan_hdd_set_txq_params,
21655#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021656 .get_station = wlan_hdd_cfg80211_get_station,
21657 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21658 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021659 .add_station = wlan_hdd_cfg80211_add_station,
21660#ifdef FEATURE_WLAN_LFR
21661 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21662 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21663 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21664#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021665#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21666 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21667#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021668#ifdef FEATURE_WLAN_TDLS
21669 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21670 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21671#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021672#ifdef WLAN_FEATURE_GTK_OFFLOAD
21673 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21674#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021675#ifdef FEATURE_WLAN_SCAN_PNO
21676 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21677 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21678#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021679 .resume = wlan_hdd_cfg80211_resume_wlan,
21680 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021681 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021682#ifdef WLAN_NL80211_TESTMODE
21683 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21684#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021685 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21687 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021688 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021689#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021690#ifdef CHANNEL_SWITCH_SUPPORTED
21691 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21692#endif
21693
Jeff Johnson295189b2012-06-20 16:38:30 -070021694};
21695